我有一份清单清单:
colours=[["#660000","#863030","#ba4a4a","#de7e7e","#ffaaaa"],["#a34b00","#d46200","#ff7a04","#ff9b42","#fec28d"],["#dfd248","#fff224","#eefd5d","#f5ff92","#f9ffbf"],["#006600","#308630","#4aba4a","#7ede7e","#aaffaa"]]
搜索列表的最简洁方法是什么,并返回其中一个项目的位置,例如"#660000"
?
我查看了索引方法,但似乎没有解压缩列表中的列表。
postion=colours.index("#660000")
提供:ValueError: ['#660000'] is not in list
,而非[0][0]
正如我所期望的那样......
答案 0 :(得分:15)
我会做这样的事情:
[(i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour]
这将返回一个元组列表,其中第一个索引是第一个列表中的位置,第二个索引是第二个列表中的位置(注意:c
是您要查找的颜色,即"#660000"
)。
对于问题中的示例,返回的值为:
[(0, 0)]
如果您只是需要找到以懒惰方式找到颜色的第一个位置,您可以使用它:
next(((i, colour.index(c))
for i, colour in enumerate(colours)
if c in colour),
None)
这将返回找到的第一个元素的元组,如果没有找到元素,则返回None
(如果没有,则还可以删除上面的None
参数将引发StopIteration
异常元素被发现)。
编辑:正如@RikPoggi正确指出的那样,如果匹配数量很高,这将引入一些开销,因为colour
被迭代两次以找到c
。我认为这对于少量匹配是合理的并且对单个表达式有答案。但是,为避免这种情况,您还可以使用以下相同的想法定义方法:
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')]
请注意,由于find
是一个生成器,因此您可以实际使用它,如上例中的next
一样,在第一场比赛时停止并跳过进一步查看。
答案 1 :(得分:8)
使用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)
答案 2 :(得分:4)
如果你想避免两次迭代目标子列表,那么最佳(也是最Pythonic)方式似乎是一个循环:
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)
答案 3 :(得分:3)
使用numpy
:
>>> import numpy
>>> ar = numpy.array(colours)
>>> numpy.where(ar=="#fff224")
(array([2]), array([1]))
如您所见,您将获得包含所有行和列索引的元组。
答案 4 :(得分:0)
在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)
答案 5 :(得分:-2)
你可以做的另一件事是选择你想要的列表部分,然后使用索引来找到它
list_name[0].index("I want coffee")