我是Python的新手,我做了我的搜索,但我找不到我要找的东西。如果有人提出这个问题,我会提前道歉,如果由于我不知道我想要达到的名字而无法找到它。我很乐意阅读您可能建议的任何文件。
我有一份清单清单。例如=> [int,'str']
t = [[0234, 'str_0'],
[1267, 'str_1'],
[2445, 'str_2']]
我想知道 {t>} 是否存在于 list t 列表之一的index(1)位置。 我可以使用包含2 for或while循环的函数来执行此操作,但我正在寻求的是,如果可能,使用一次迭代来实现此目的。我想学习最短的功能。
a str
(在其第一个索引位置上具有str_3的列表的索引)
对于str_1,我想得到int(0)
和 str_1234 我希望 False ,因为它不在 for input str('str_3'), I want to get int(2)
>中的任何列表中p>
作为新手,我通常会这样做:
list t
我想要获得的是,如果可能的话,在一行代码中实现这一目标的更好更短的方法,或者只是为了了解是否有更智能,更好或更多的pythonic方式,你们中的任何一个人肯定会有更多有经验的人推荐。
谢谢
答案 0 :(得分:11)
[n for n, (i, s) in enumerate(t) if s == 'str_3']
说明:
>>> t = [[100, 'str_1'], [200, 'str_2'], [300, 'str_3']]
# Use enumerate to get each list item along with its index.
>>> list(enumerate(t))
[(0, [100, 'str_1']), (1, [200, 'str_2']), (2, [300, 'str_3'])]
# Use list comprehension syntax to iterate over the enumeration.
>>> [n for n, (i, s) in enumerate(t)]
[0, 1, 2]
# An if condition can be added right inside the list comprehension.
>>> [n for n, (i, s) in enumerate(t) if s == 'str_3']
[2]
>>> [n for n, (i, s) in enumerate(t) if s == 'str_1234']
[]
这将返回所有匹配的索引,因为可能有多个匹配索引。
如果你知道只有一个索引,我可以建议使用dict而不是嵌套列表吗?使用dict,您可以使用非常简单的语法在恒定时间内查找元素,而不必迭代。
>>> t = {'str_1': 100, 'str_2': 200, 'str_3': 300}
>>> 'str_3' in t
True
>>> t['str_3']
300
>>> 'str_1234' in t
False
>>> t['str_1234']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'str_1234'
答案 1 :(得分:7)
将any
function与生成器表达式一起使用:
any(el[1] == 'str_1' for el in t)
这样做是循环t
,对于el
中的每个t
,我们测试其中的第二个值是否等于str_1
,就像你的循环一样
但它只会在找到一个真实的元素,然后停止,返回True
之前执行此操作。如果找不到这样的元素,它将返回False
。
相反,如果您不仅想测试str_1
的存在,而且还想知道它的位置,那么最有效的方法是使用像您一样的循环。您可以使用enumerate
为序列提供索引和值:
for n, el in enumerate(t):
if el[1] == 'str_1'
return n
return False
答案 2 :(得分:3)
你给出的for循环的例子不是在python中使用for循环的常用方法,因为for循环不是数字构造(就像在大多数语言中一样),而是一种应用循环体的方法由给定集合的迭代产生的每个元素。
正常的方式(使用循环)来查找索引将是:
for (n, (integer, string)) in enumerate(t):
if 'str1' == string:
return n
请注意,在这种情况下,序列分配用于将每个两项列表的元素分配给单独的变量。在python shell中自己尝试enumerate
函数,找出它的作用。
如果您的列表已排序,您可能希望使用bisect
:http://docs.python.org/library/bisect.html
如果您只是想知道是否有符合条件的对,并且您不关心索引,请使用any
,这会在找到匹配后停止迭代:
any(string == 'str_1' for integer, string in t)
any
内的表达式是生成器表达式,它为t中的每个元素生成True
或False
。
最后,考虑一下这是否真的是最合适的数据结构。
答案 3 :(得分:1)
首先,让我们做一个类似于你所描述的实际数据结构:
>>> LoL=[[i,'str_{}'.format(i)] for i in list(range(10))+list(range(10,0,-1))]
# this is Py 3, so that is why I need 'list' around range
>>> LoL
[[0, 'str_0'], [1, 'str_1'], [2, 'str_2'], [3, 'str_3'], [4, 'str_4'], [5, 'str_5'],
[6, 'str_6'], [7, 'str_7'], [8, 'str_8'], [9, 'str_9'], [10, 'str_10'], [9, 'str_9'],
[8, 'str_8'], [7, 'str_7'], [6, 'str_6'], [5, 'str_5'], [4, 'str_4'], [3, 'str_3'],
[2, 'str_2'], [1, 'str_1']]
现在为每个匹配等于'str_5'的测试的元素列出元组列表
>>> [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == 'str_5']
[(5, 5, 'str_5'), (15, 5, 'str_5')]
现在,使用不存在的字符串进行测试:
>>> [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == 'str_123']
[]
然后很容易测试存在,计算事件并提取所需的项目:
>>> for t in [(i,li,ls) for (i,(li,ls)) in enumerate(LoL) if ls == target]:
... print('index: {}, int: {}, str: "{}"'.format(*t))
...
index: 7, int: 7, str: "str_7"
index: 13, int: 7, str: "str_7"
正如其他人所说,你可以重新构建你的数据结构。您是否将int_x
作为索引?不要那样做。使用字符串列表并枚举。如果它只是str_x和int_x之间的映射,请使用字典。