mat*_*ien 1 python loops list append
假设我有以下名单:
names = [['Matt', 'Matt', 'Paul'], ['Matt']]
Run Code Online (Sandbox Code Playgroud)
我只想返回列表中的“Matts”,但我也想维护列表结构的列表。所以我想返回:
[['Matt', 'Matt'], ['Matt']]
Run Code Online (Sandbox Code Playgroud)
我有这样的东西,但这会将所有内容一起附加到一个大列表中:
matts = [name for namelist in names for name in namelist if name=="Matt"]
Run Code Online (Sandbox Code Playgroud)
我知道这样的事情是可能的,但我想避免迭代列表和附加。这可能吗?
names = [['Matt', 'Matt', 'Paul'], ['Matt']]
matts = []
for namelist in names:
matts_namelist = []
for name in namelist:
if name=="Matt":
matts_namelist.append(name)
else:
pass
matts.append(matts_namelist)
Run Code Online (Sandbox Code Playgroud)
使用嵌套列表理解,如下所示:
\nnames = [[\'Matt\', \'Matt\', \'Paul\'], [\'Matt\']]\nres = [[name for name in lst if name == "Matt"] for lst in names]\nprint(res)\nRun Code Online (Sandbox Code Playgroud)\n输出
\n[[\'Matt\', \'Matt\'], [\'Matt\']]\nRun Code Online (Sandbox Code Playgroud)\n上面的嵌套列表推导式等价于下面的 for 循环:
\nres = []\nfor lst in names:\n res.append([name for name in lst if name == "Matt"])\nprint(res)\nRun Code Online (Sandbox Code Playgroud)\n\nfrom operator import eq\nfrom functools import partial\n\nnames = [[\'Matt\', \'Matt\', \'Paul\'], [\'Matt\']]\n\neq_matt = partial(eq, "Matt")\nres = [[*filter(eq_matt, lst)] for lst in names]\nprint(res)\nRun Code Online (Sandbox Code Playgroud)\n微基准测试
\n%timeit [[*filter(eq_matt, lst)] for lst in names]\n56.3 \xc2\xb5s \xc2\xb1 519 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n%timeit [[name for name in lst if "Matt" == name] for lst in names]\n26.9 \xc2\xb5s \xc2\xb1 355 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\nRun Code Online (Sandbox Code Playgroud)\n设置 (微基准)
\nimport random\npopulation = ["Matt", "James", "William", "Charles", "Paul", "John"]\nnames = [random.choices(population, k=10) for _ in range(50)]\nRun Code Online (Sandbox Code Playgroud)\n完整基准测试
\n候选人
\ndef nested_list_comprehension(names, needle="Matt"):\n return [[name for name in lst if needle == name] for lst in names]\n\n\ndef functional_approach(names, needle="Matt"):\n eq_matt = partial(eq, needle)\n return [[*filter(eq_matt, lst)] for lst in names]\n\n\ndef count_approach(names, needle="Matt"):\n return [[needle] * name.count(needle) for name in names]\nRun Code Online (Sandbox Code Playgroud)\n绘图\n
上述结果是针对包含 100 到 1000 个元素的列表获得的,其中每个元素都是从 14 个字符串(名称)总体中随机选择的 10 个字符串的列表。可以在此处找到用于重现结果的代码。\n从图中可以看出,性能最佳的解决方案是来自@rv.kvetch 的解决方案。
\n