Search in lists of lists by given index
You're always going to have a loop - someone might come along with a clever one-liner that hides the loop within a call to map()
or similar, but it's always going to be there.
My preference would always be to have clean and simple code, unless performance is a major factor.
Here's perhaps a more Pythonic version of your code:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
for sublist in data:
if sublist[1] == search:
print "Found it!", sublist
break
# Prints: Found it! ['a', 'c']
It breaks out of the loop as soon as it finds a match.
(You have a typo, by the way, in ['b''d']
.)
Find the index of an item in a list of lists
I'd do something like this:
[(i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour]
This will return a list of tuples where the first index is the position in the first list and second index the position in the second list (note: c
is the colour you're looking for, that is, "#660000"
).
For the example in the question, the returned value is:
[(0, 0)]
If you just need to find the first position in which the colour is found in a lazy way you can use this:
next(((i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour),
None)
This will return the tuple for the first element found or None
if no element is found (you can also remove the None
argument above in it will raise a StopIteration
exception if no element is found).
Edit: As @RikPoggi correctly points out, if the number of matches is high, this will introduce some overhead because colour
is iterated twice to find c
. I assumed this to be reasonable for a low number of matches and to have an answer into a single expression. However, to avoid this, you can also define a method using the same idea as follows:
def find(c):
for i, colour in enumerate(colours):
try:
j = colour.index(c)
except ValueError:
continue
yield i, j
matches = [match for match in find('#660000')]
Note that since find
is a generator you can actually use it as in the example above with next
to stop at the first match and skip looking further.
Process a list of lists, finding all lists that have matching last values?
1. Using collections.defaultdict
You can use defaultdict
to the first group up your items with more than one occurrence, then, iterate over the dict.items
to get what you need.
from collections import defaultdict
lol = [[0,'a'], [0,'b'],
[1,'b'], [1,'c'],
[2,'d'], [2,'e'],
[2,'g'], [2,'b'],
[3,'e'], [3,'f']]
d = defaultdict(list)
for v,k in lol:
d[k].append(v)
# d looks like -
# defaultdict(list,
# {'a': [0],
# 'b': [0, 1, 2],
# 'c': [1],
# 'd': [2],
# 'e': [2, 3],
# 'g': [2],
# 'f': [3]})
result = [[v,k] for k,vs in d.items() for v in vs if len(vs)>1]
print(result)
[[0, 'b'], [1, 'b'], [2, 'b'], [2, 'e'], [3, 'e']]
2. Using pandas.duplicated
Here is how you can do this with Pandas -
- Convert to pandas dataframe
- For key column, find the duplicates and keep all of them
- Convert to list of records while ignoring index
import pandas as pd
df = pd.DataFrame(lol, columns=['val','key'])
dups = df[df['key'].duplicated(keep=False)]
result = list(dups.to_records(index=False))
print(result)
[(0, 'b'), (1, 'b'), (2, 'e'), (2, 'b'), (3, 'e')]
3. Using numpy.unique
You can solve this in a vectorized manner using numpy -
- Convert to numpy matrix
arr
- Find unique elements
u
and their countsc
- Filter list of unique elements that occur more than once
dup
- Use broadcasting to compare the second column of the array and take any over axis=0 to get a boolean which is True for duplicated rows
- Filter the
arr
based on this boolean
import numpy as np
arr = np.array(lol)
u, c = np.unique(arr[:,1], return_counts=True)
dup = u[c > 1]
result = arr[(arr[:,1]==dup[:,None]).any(0)]
result
array([['0', 'b'],
['1', 'b'],
['2', 'e'],
['2', 'b'],
['3', 'e']], dtype='<U21')
Python finding a value in a list of lists
Yes, no need for range, for starters
for hay in haystack:
if needle in hay:
return hay
And if you really really need the index, use enumerate
for x, hay in enumerate(haystack):
if needle in hay:
return x
Finding the index of an item in a list of lists
Just use enumerate
:
l = [[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]
# e.g.: find the index of the list containing 12
# This returns the first match (i.e. using index 0), if you want all matches
# simply remove the `[0]`
print [i for i, lst in enumerate(l) if 12 in lst][0]
This outputs:
[2]
Edit:
@hlt's comment suggests using the following for more efficient behavior:
next(i for i,v in enumerate(l) if 12 in v)
Using a list of lists containing indexes to pull strings by index from another list
[[list_of_text[idx-1] for idx in indices] for indices in list_of_indexes]
Find a number in list of lists
Lists are not the best data structure to look for elements, you should consider using sets, which gives you O(1) time for lookup. There are better data structures and algorithms if your lists don't have intersections, but since you want all the lists, there are fewer alternatives.
lsts = [[0,1,2,3,4,5], [6,7,8,9,10,11], [12,56,86,9], [55,53,12]]
sets = map(set, lsts)
def find(iterables, element):
return [i for i, iterable in enumerate(iterables) if element in iterable]
How to find index of a given value in a nested list in Python?
Everything seems fine in your code, just make the string formatter a tuple. Modify the last line of your code to this below:
print('the index of 1 is [%d][%d] ' % (item,item2))
Related Topics
Is There Any Difference Between "Foo Is None" and "Foo == None"
How to Scrape a Website Which Requires Login Using Python and Beautifulsoup
Pandas Create New Column with Count from Groupby
Exif Manipulation Library for Python
Too Many Different Python Versions on My System and Causing Problems
Sqlalchemy Create_All() Does Not Create Tables
How Does This Input Work with the Python 'Any' Function
How to Get Most Informative Features for Scikit-Learn Classifiers
Matplotlib Legend Markers Only Once
Pandas Dataframe Concat VS Append
List of Dicts To/From Dict of Lists
Django Aggregation: Summation of Multiplication of Two Fields
Nested for Loops Using List Comprehension
Change the Colors Within Certain Range to Another Color Using Opencv
Python How to Pad Numpy Array with Zeros
Python Eval: Is It Still Dangerous If I Disable Builtins and Attribute Access