我想遍历两个列表。第一个列表包含一些浏览器用户代理,第二个列表包含这些浏览器的版本。我只想过滤那些版本大于60的用户代理。
这是我的列表理解的样子:
[link for ver in version for link in useragents if ver > 60]
此列表的问题是它多次打印相同的用户代理。我使用zip
函数编写了以下代码,效果很好:
for link, ver in zip(useragents, version):
if ver > 60:
# append to list
print(link)
为什么列表推导会返回意外结果?
答案 0 :(得分:25)
您的第一个列表理解等同于:
res = []
for ver in version:
for link in useragents:
if ver > 60:
res.append(link)
请注意,您具有时间复杂度为O( n 2 )的嵌套循环,即您要遍历{{1}的每个组合 }和version
。假设您的useragents
和version
列表对齐,那不是您想要的。
等效于useragents
的是以下列表理解:
for
答案 1 :(得分:8)
[link for (link, ver) in zip(useragents, version) if ver > 60]
您仍然必须将两个列表压缩在一起。
答案 2 :(得分:5)
此
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode != RESULT_OK)
return;
else {
Uri treeUri = resultData.getData();
Log.e("treeuri",treeUri.toString());
grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if(Build.VERSION.SDK_INT >= 19)
getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
String str = treeUri.toString();
try{
File dir = new File (Environment.getExternalStorageDirectory().getAbsolutePath());
if(!dir.exists()){
dir.mkdir();
}
FileOutputStream fos = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"/treeuri.txt", true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos));
writer.write(str);
writer.flush();
writer.close();
fos.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
与zip不同。它不是并行遍历两个序列。它正在迭代这两个序列的所有组合。
就好像你写了:
[link for ver in version for link in useragents if ver > 60]
因此,如果两个序列的长度均为5,则将有25种组合(其中有些被条件for ver in version:
for link in useragents:
if ver > 60:
# append(link)
过滤掉了。)
当您想要并行处理序列时,ver > 60
是做到这一点的一种方法,即使是在理解方面也是如此。
zip
答案 3 :(得分:2)
或者,您可以将功能compress()
与map()
结合使用,在其中检查某些条件:
from itertools import compress
filter_ = map(lambda x: x > 60, version)
list(compress(useragents, filter_))
s = 'ABCDEFG'
nums = range(len(s))
filter_ = map(lambda x: x > 3, nums)
print(list(compress(s, filter_)))
# ['E', 'F', 'G']
答案 4 :(得分:0)
在没有数据的情况下无法确定发生了什么,但是通常,“双重”列表理解与zip
不同,而是双重循环,即
[a for b in bs for a in as]
等同于
for b in bs:
for a in as:
lst.append(a)