I've got a function that I'd like to improve.
It takes a list of lists and a "target" element, and it returns the set
of the items in the lists that appear either before or after the target
item. (Actually, it's a generator, and I use the set class outside of
it to collect the unique items, but you get the idea. ;-) )
data = [
['this', 'string', 'is', 'nice'],
['this', 'string', 'sucks'],
['string', 'not', 'good'],
['what', 'a', 'string']
]
def f(target, ListOfLists):
for N in ListOfLists:
try:
i = N.index(target)
except ValueError:
continue
# item before target
if i: yield N[i - 1]
# item after target
try:
yield N[i + 1]
except IndexError:
pass
print set(n for n in f('string', data))
# Prints set(['this', 'not', 'is', 'sucks', 'a'])
Now, this works and normally I'd be happy with this and not try to
improve it unless I found that it was a bottleneck. However, in this
case I know that when a try..except statement fails (i.e. executes the
except part of the statement) it's "slow", *and* I know that the real
list of lists will have many lists in it in which the target item does
not appear.
That means that the first try..except statement will be executing it's
except clause more than half the time, and probably *much* more than
half the time.
This little problem strikes me as one of those fun puzzles that are a
joy to solve in python, so rather than keep it to myself I thought I'd
post it here on c.l.p and see what folks could come up with.
I'm not so much looking for simple improvements like
def f(target, ListOfLists):
for N in ListOfLists:
if target not in N:
continue
i = N.index(target)
# etc...
but rather cool, elegant, efficient, "pythonic" different ways to do
it.
I love these kinds of puzzles but I know the combined "might" of
comp.lang.pytho n can come up with stuff I would never dream of, so, um,
here you go.
About the input data:
1) there are many lists, several hundred or thousand, perhaps even tens
of thousand
2) most of them will have less than 5 items, and almost all of them
less than 20, I don't know the maximum length but it will be less than
50 or so
3) The target occurs at most once in each list. (*no* item is
duplicated within a single list, all elements of a list are unique to
that list but may recur in other lists)
4) *most* of the lists will not contain the target
5) The data are not static, but they do change less often than this
function will be called. I don't know yet, but I'd say that this
function will be called maybe 10 times more often than the list of
lists will be modified.
6) Changes to the data will all be either adding or removing lists, the
lists themselves won't be modified.
7) The form of the data can be other than a list of lists, i.e. a set
of tuples, a list of tuples, a tuple of lists (although that would
require creating a new tuple when the data are modified, see 6)
whatever.
8) Building auxiliary data structures is fine (like a dict mapping
targets to lists they appear in, or to the sets that the function
returns ("memoizing" )) but while speed is the main concern, memory
usage shouldn't be flagrant. Changing the data should be fast, so
rebuilding the auxiliary data structures shouldn't be expensive
Let's see, I guess that's about it. Thanks in advance.
Peace,
~Simon
--
"The history of mankind for the last four centuries is rather like that
of an imprisoned sleeper, stirring clumsily and uneasily while the
prison that restrains and shelters him catches fire, not waking but
incorporating the crackling and warmth of the fire with ancient and
incongruous dreams, than like that of a man consciously awake to danger
and opportunity." --H. P. Wells, "A Short History of the World" 1 1681
Simon Forman wrote:
I've got a function that I'd like to improve.
It takes a list of lists and a "target" element, and it returns the set
of the items in the lists that appear either before or after the target
item. (Actually, it's a generator, and I use the set class outside of
it to collect the unique items, but you get the idea. ;-) )
data = [
['this', 'string', 'is', 'nice'],
['this', 'string', 'sucks'],
['string', 'not', 'good'],
['what', 'a', 'string']
]
def f(target, ListOfLists):
for N in ListOfLists:
try:
i = N.index(target)
except ValueError:
continue
# item before target
if i: yield N[i - 1]
# item after target
try:
yield N[i + 1]
except IndexError:
pass
print set(n for n in f('string', data))
# Prints set(['this', 'not', 'is', 'sucks', 'a'])
Now, this works and normally I'd be happy with this and not try to
improve it unless I found that it was a bottleneck. However, in this
case I know that when a try..except statement fails (i.e. executes the
except part of the statement) it's "slow", *and* I know that the real
list of lists will have many lists in it in which the target item does
not appear.
That means that the first try..except statement will be executing it's
except clause more than half the time, and probably *much* more than
half the time.
Nevermind, it turns out that each list in the list of lists will
*always* contain the target item, making this task much less
interesting.
~Simon This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: kevin parks |
last post by:
hi. I've been banging my head against this one a while and have asked
around, and i
am throwing this one out there in the hopes that some one can shed
some light on
what has turned out to be a tough problem for me (though i am getting
closer).
i have been mucking with a lot of data in a dictionary that looks
like:
|
by: Charlotte Henkle |
last post by:
Hello;
I'm pondering how to count the number of times an item appears in
total in a nested list. For example:
myList=,,]
I'd like to know that a appeared three times, and b appeared twice,
and the rest appeard only once.
|
by: Peter Collinson |
last post by:
Hi...
Is there any way to style a List Item a different color and size than
the <LI> in an Ordered List?
I'd like a red super-script number and a dark blue text in a page's
footnotes. And this be done using style sheets?
--
- Yours truly, Pete Collinson
|
by: Kay |
last post by:
Hello,
I have two list boxes on my form, one initially displays with items and the
other displays blank, by clicking a button, it is possible to move items
from one box to another and vice a versa, this works fine. I also have a
dropdown list on the page with autopost back = true, my problem is as
follows: when the user selects an option in the dropdown list the form is
posted back to the server and certain other processing happens, then...
|
by: Giovanni Bassi |
last post by:
Hello All,
I have a class implementing IList and a global object of this class type.
I have two different form objects. One has a ListBox and the other has
ComboBox. Both of their datasources are set to this global object.
The problem is that when I select an item in the ListBox the combobox
selecteditem changes to the same item selected in the ListBox. And the
oposite is also true, so when I select an item in the ComboBox my ListBox...
| |
by: rshepard |
last post by:
While working with lists of tuples is probably very common, none of my
five Python books or a Google search tell me how to refer to specific items
in each tuple. I find references to sorting a list of tuples, but not
extracting tuples based on their content.
In my case, I have a list of 9 tuples. Each tuple has 30 items. The first
two items are 3-character strings, the remaining 28 itmes are floats.
I want to create a new list from...
|
by: Simon Forman |
last post by:
Is there a more efficient way to do this?
def f(L):
'''Return a set of the items that occur more than once in L.'''
L = list(L)
for item in set(L):
L.remove(item)
return set(L)
|
by: jameswilkinsonfjs |
last post by:
Hi All,
Ok I have a table - it lists items with a unique reference
code; lets say there are 4 items :
Item RefCode
1 ABC1
2 ABC2
3 ABC3
4 ABC4
|
by: =?Utf-8?B?YW1pcg==?= |
last post by:
Hi,
I have a Generic Object that has a private List field item.
I populate the List in a different function
I use a FOREACH LOOP with a FindAll function to get all items that have a
certain match for data in the list and do something to it.
The problem is that it repeats for all data items in the list and not
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |