elegant find sub-list in list
I know this question is 5 months old and already "accepted", but googling a very similar problem brought me to this question and all the answers seem to have a couple of rather significant problems, plus I'm bored and want to try my hand at a SO answer, so I'm just going to rattle off what I've found.
The first part of the question, as I understand it, is pretty trivial: just return the original list with all the elements not in the "pattern" filtered out. Following that thinking, the first code I thought of used the filter() function:
def subfinder(mylist, pattern):
return list(filter(lambda x: x in pattern, mylist))
I would say that this solution is definitely more succinct than the original solution, but it's not any faster, or at least not appreciably, and I try to avoid lambda expressions if there's not a very good reason for using them. In fact, the best solution I could come up with involved a simple list comprehension:
def subfinder(mylist, pattern):
pattern = set(pattern)
return [x for x in mylist if x in pattern]
This solution is both more elegant and significantly faster than the original: the comprehension is about 120% faster than the original, while casting the pattern into a set first bumps that up to a whopping 320% faster in my tests.
Now for the bonus: I'll just jump right into it, my solution is as follows:
def subfinder(mylist, pattern):
matches = []
for i in range(len(mylist)):
if mylist[i] == pattern[0] and mylist[i:i+len(pattern)] == pattern:
matches.append(pattern)
return matches
This is a variation of Steven Rumbalski's "inefficient one liner", that, with the addition of the "mylist[i] == pattern[0]" check and thanks to python's short-circuit evaluation, is significantly faster than both the original statement and the itertools version (and every other offered solution as far as I can tell) and it even supports overlapping patterns. So there you go.
Is there an elegant way to find an item in a list of list with multiple layers in python
If you don't want to flatten the array, you can use recursion to iterate over a list and recurs on each another list inside it.
Code:
def check(lst, x):
for i in range(len(lst)):
if type(lst[i]) == list: # If there is another list inside it
if check(lst[i], x): # If the value x exist in lst[i]
return True
elif lst[i] == x: # If there is no more list inside it
return True
return False # X can't be found in lst.
print(check([0, [1, [2, [3]]], [4, [5]], 6], 5)) # Output: True
print(check([0, [1, [2, [3]]], [4, [5]], 6], 9)) # Output: False
Find the position of sublist in a list in python
x = [0,1,2,3,4,5,6,7]
y = [3,4,5]
occ = [i for i, a in enumerate(x) if a == y[0]]
for b in occ:
if x[b:b+len(y)] == y:
print 'YES-- SUBLIST at : ', b
break
if len(occ)-1 == occ.index(b):
print 'NO SUBLIST'
break
What's an elegant way to extract a series of entries in a list of tuples into sublists?
You can use tuple()
function to transform lists into tuples, so you will be able to append all of the tuples inside listOfTuples
variable into the output that you need:
TRUE = 1
lot = [('selectable', 'frequency'), ('color', 'green'), ('item', '10 Hz'),
('value', 10), ('align', 'left'), ('hidden', TRUE), ('item', '20 Hz'),
('value', 20), ('align', 'right'), ('item', '50 Hz'), ('value', 50),
('item', '100 Hz'), ('value', 100), ('textColor', 0xFF0000)]
l = [[]]
for i in lot:
if i[0]=='item':
l[-1] = tuple(l[-1])
l.append([])
l[-1].append(i)
print(l[1:])
Output:
[(('item', '10 Hz'), ('value', 10), ('align', 'left'), ('hidden', 1)), (('item', '20 Hz'), ('value', 20), ('align', 'right')), (('item', '50 Hz'), ('value', 50)), [('item', '100 Hz'), ('value', 100), ('textColor', 16711680)]]
The only disadvantage of this method is that you need to remove the first element of the output list of tuples, so it may doesn't work in certain situations.
My code works but need an elegant way to produce sub-lists out of a list
You can just write a list comprehension to achieve the result you want:
lst = [0, 10]
slotss = 4
out_lst = [[start, start + (slotss - 1)] for start in range(lst[0], lst[1] - (slotss - 1))]
Output:
[[0, 3], [1, 4], [2, 5], [3, 6], [4, 7], [5, 8], [6, 9]]
Most programmatically elegant (pythonic) way to take ith element of list of lists of lists, and create lists of these ith elements
Your original code isn't bad at all. These existing answers are great, but I think
result = []
for item in lll:
result.extend(zip(*item))
is reasonably succinct and Pythonic, arguably more readable than a one-liner, no imports and worth consideration. extend
is a common refactor for append
+ loop for flattening lists and zip
is almost always the way to go for columnwise iteration and matrix rotation.
If you need lists instead of tuples:
result = []
for item in lll:
result.extend([list(x) for x in zip(*item)])
or with map
:
for item in lll:
result.extend(map(list, zip(*item)))
A couple of minor style suggestions courtesy of PEP-8:
snake_case
is preferred overcamelCase
.- Avoid
l
as a variable name. It's too easily confused fori
and1
.
Also, num_things = len(item[0])
strikes me as a bit dangerous because it'll raise an IndexError
if item
is empty.
Finding all list and sublist combination from flat list
Question is quite vague, I think what you are looking for is set-partitions:
def partition(collection):
if len(collection) == 1:
yield [ collection ]
return
first = collection[0]
for smaller in partition(collection[1:]):
# insert `first` in each of the subpartition's subsets
for n, subset in enumerate(smaller):
yield smaller[:n] + [[ first ] + subset] + smaller[n+1:]
# put `first` in its own subset
yield [ [ first ] ] + smaller
something = ['a', 'b', 'c']
for n, p in enumerate(partition(something), 1):
print(n, sorted(p))
Output:
1 [['a', 'b', 'c']]
2 [['a'], ['b', 'c']]
3 [['a', 'b'], ['c']]
4 [['a', 'c'], ['b']]
5 [['a'], ['b'], ['c']]
Get information out of sub-lists in main list elegantly
I think you can certainly make your code more concise and easier to read by using defaultdict
to create a dictionary from the first two elements in each sublist to all the third items:
from collections import defaultdict
nums = defaultdict(list)
for arr in a:
key = tuple(arr[:2]) # make the first two floats the key
nums[key].append( arr[2] ) # append the third float for the given key
a_processed = [[k[0], k[1], sum(vals)/len(vals)] for k, vals in nums.items()]
Using this, I get the same output as you (albeit in a different order):
[[0.2, 1.1, 0.8], [1.2, 0.3, 0.6], [0.3, 1.4, 0.2], [0.6, 0.4, 0.9], [1.1, 0.5, 0.6666666666666666], [0.6, 0.2, 0.75]]
If the order of a_processed
is an issue, you can use an OrderedDict
, as pointed out by @DSM.
What is the most elegant way of finding the n-length consecutive sub-lists of a list in Python?
>>> some_lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l = [some_lst[i:i+3] for i in xrange(len(some_lst)-2)]
Related Topics
Split a List into Parts Based on a Set of Indexes in Python
Check What Files Are Open in Python
How to Decorate an Instance Method with a Decorator Class
Getting Only Element from a Single-Element List in Python
How to Display a Pandas Data Frame with Pyqt5/Pyside2
How to Create an Encrypted Zip File
How to Load Files Using Pickle and Multiple Modules
Pycharm Current Working Directory
Easy Way of Finding Decimal Places
How to Run an Ipython Magic from a Script (Or Timing a Python Script)
Update Tkinter Label from Variable
Use Python's String.Replace VS Re.Sub
Python Random Sample with a Generator/Iterable/Iterator
Return String with First Match for a Regex, Handling Case Where There Is No Match