简体   繁体   English

Python 条件迭代的列表理解

[英]Python List comprehension with conditional iteration

Just want to ask if this particular set of code can be expressed into a one-liner list comprehension:只是想问一下这组特定的代码是否可以表示为单行列表理解:

files = ["country_Maldives", "country_East Timor", "country_Laos", "country_Uruguay"]
accountlist = ["Laos", "Maldives"]

final_list = []
for account in accountlist:
    included = [file for file in files if account in file][0]
    final_list.append(included)

Thank you.谢谢你。

Since your code just fetches all the matches and picks the first one with:由于您的代码只是获取所有匹配项并选择第一个匹配项:

[file for file in files if account in file][0]

You could instead use next() to keep retrieving the next item until a match is found:您可以改为使用next()继续检索下一项,直到找到匹配项:

result = [next(file for file in files if account in file) for account in accountlist]

print(result)
# ['country_Laos', 'country_Maldives'] => Same output as your original code

The only problem with the above is that aStopIteration exception will be raised if the iterator is exhausted and no match has been found.上面的唯一问题是,如果迭代器用尽并且找不到匹配项,则会引发StopIteration异常。 To prevent this, we can supply a default value instead, such as None , so it returns this value instead of the exception.为了防止这种情况,我们可以提供一个默认值,例如None ,所以它返回这个值而不是异常。

[next((file for file in files if account in file), None) for account in accountlist]

Then if we wanted to filter out None matches, we could use another list comprehension to do that:然后,如果我们想过滤掉None匹配项,我们可以使用另一个列表推导来做到这一点:

filtered = [file for file in result if file is not None]

Check out any/all operators:查看any/all运算符:

ret = [file for file in files if any(account in file for account in accountlist)]

https://docs.python.org/3/library/functions.html#any https://docs.python.org/3/library/functions.html#any

UDP UDP

Oneliner above returns list of ALL files each of which contains ANY of accounts.上面的 Oneliner 返回所有文件的列表,每个文件都包含任何帐户。 If you want to find only first entries by given condition, operator next is also worth mentioning:如果您只想按给定条件查找第一个条目,运算符next也值得一提:

ret = [next((file for file in files if account in file), []) for account in accountlist]

https://docs.python.org/3/library/functions.html#next https://docs.python.org/3/library/functions.html#next

just another way, nesting the for loops...只是另一种方式,嵌套for循环......

In [19]: files = ["country_Maldives", "country_East Timor", "country_Laos", "country_Uruguay"]
    ...: accountlist = ["Laos", "Maldives"]

In [20]: res=[file  for acc in accountlist for file in files  if acc in file.split('_')]

In [21]: res
Out[21]: ['country_Laos', 'country_Maldives']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM