[英]Find the index of an item in a list of lists
I have a list of lists:我有一个列表列表:
colours = [["#660000","#863030","#ba4a4a","#de7e7e","#ffaaaa"],["#a34b00","#d46200","#ff7a04","#ff9b42","#fec28d"],["#dfd248","#fff224","#eefd5d","#f5ff92","#f9ffbf"],["#006600","#308630","#4aba4a","#7ede7e","#aaffaa"]]
What's the cleanest way of searching the list and returning the position of one of the items, eg "#660000"
?搜索列表并返回其中一项的位置的最简洁方法是什么,例如
"#660000"
?
I have looked at the index
method, but that doesn't seem to unpack the list inside the list.我已经查看了
index
方法,但这似乎并没有将列表中的列表解包。
postion = colours.index("#660000")
gives: ValueError: ['#660000'] is not in list
, not [0][0]
as I expect...给出:
ValueError: ['#660000'] is not in list
, not [0][0]
正如我所期望的......
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"
).这将返回一个元组列表,其中第一个索引是第一个列表中的位置,第二个索引是第二个列表中的位置(注意:
c
是您要查找的颜色,即"#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).这将返回找到的第一个元素的元组,如果没有找到元素,则返回
None
(您也可以删除上面的None
参数,如果没有找到元素,它将引发StopIteration
异常)。
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
.编辑:正如@RikPoggi 正确指出的那样,如果匹配数很高,这将引入一些开销,因为
colour
被迭代两次以找到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.请注意,由于
find
是一个生成器,您实际上可以像上面的示例一样使用它, next
在第一场比赛时停止并跳过进一步查找。
Using enumerate()
you could write a function like this one:使用
enumerate()
你可以写一个这样的函数:
def find(target):
for i,lst in enumerate(colours):
for j,color in enumerate(lst):
if color == "#660000":
return (i, j)
return (None, None)
If you want to evade from iterating the target sublist twice, it seems that the best (and the most Pythonic) way to go is a loop:如果你想避免迭代目标子列表两次,似乎最好的(也是最 Python 化的)方法是循环:
def find_in_sublists(lst, value):
for sub_i, sublist in enumerate(lst):
try:
return (sub_i, sublist.index(value))
except ValueError:
pass
raise ValueError('%s is not in lists' % value)
In Python 3, I used this pattern:在 Python 3 中,我使用了这种模式:
CATEGORIES = [
[1, 'New', 'Sub-Issue', '', 1],
[2, 'Replace', 'Sub-Issue', '', 5],
[3, 'Move', 'Sub-Issue', '', 7],
]
# return single item by indexing the sub list
next(c for c in CATEGORIES if c[0] == 2)
您可以做的另一件事是选择您想要的列表部分,然后使用索引找到它
list_name[0].index("I want coffee")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.