【问题标题】:List comprehension to access a nested list within a list only in one index列表理解仅在一个索引中访问列表中的嵌套列表
【发布时间】:2021-05-04 01:46:02
【问题描述】:

我需要的是访问嵌套列表的索引以过滤元组列表中另一个索引中的元素... 例如,我有以下示例数据:

samples = [('waterfall03', 9)] 

distances = [('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232, 0.0])]

所以在这种情况下,我有示例瀑布03,其中我有数字 9,这是要从列表距离中的元组列表中的索引号 1 中删除的索引......即我想要一个列表如下[12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232]

我写了以下代码,但不工作

distances = [[n for j, n, m in enumerate(zip(subarray, samples)) if j != m] for i, subarray in enumerate(distances) if i == 1]

预期输出

distances = [('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232])]

更多测试用例

Samples = [('highway_bost321', 0), ('mountain_0871', 2), ('opencountry_043', 4), ('opencountry_053', 5), ('opencountry_123', 6), ('palace_019', 7), ('volcano_010', 8), ('waterfall03', 9)]



 distances =  [('highway_bost321', [0.0, 10.174343253183386, 10.947746706490813, 7.187637514988234, 7.660483562939873, 10.622402335214636, 10.737785768990813, 10.566917715980832, 10.819389772897063, 12.03400784892136]), ('mountain_0871', [10.947746706490813, 0.83758544921875, 0.0, 5.838234191502578, 5.363256367154217, 1.3175048828125, 3.0810546875, 6.634500456993904, 0.78460693359375, 13.91981431878607]), ('opencountry_043', [7.660483562939873, 4.668136048210366, 5.363256367154217, 2.8142531243329643, 0.0, 5.347678752303554, 3.236628762987552, 5.377074226549635, 5.634096535101808, 13.405988675235129]), ('opencountry_053', [10.622402335214636, 0.73712158203125, 1.3175048828125, 5.876377140065916, 5.347678752303554, 0.0, 3.1134033203125, 6.11476575647307, 1.97711181640625, 13.144871284931902]), ('opencountry_123', [10.737785768990813, 3.01690673828125, 3.0810546875, 5.560564920669245, 3.236628762987552, 3.1134033203125, 0.0, 5.71620618616057, 3.09417724609375, 13.597874214619402]), ('palace_019', [10.566917715980832, 5.890665007775154, 6.634500456993904, 3.7392389463104037, 5.377074226549635, 6.11476575647307, 5.71620618616057, 0.0, 6.493675414476205, 12.731745772059295]), ('volcano_010', [10.819389772897063, 1.294677734375, 0.78460693359375, 5.709877257908828, 5.634096535101808, 1.97711181640625, 3.09417724609375, 6.493675414476205, 0.0, 13.90083238519232]), ('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232, 0.0])]

预期产出

       distances =  [('highway_bost321', [10.174343253183386, 10.947746706490813, 7.187637514988234, 7.660483562939873, 10.622402335214636, 10.737785768990813, 10.566917715980832, 10.819389772897063, 12.03400784892136]), 
    ('mountain_0871', [10.947746706490813, 0.83758544921875, 5.838234191502578, 5.363256367154217, 1.3175048828125, 3.0810546875, 6.634500456993904, 0.78460693359375, 13.91981431878607]), 
    ('opencountry_043', [7.660483562939873, 4.668136048210366, 5.363256367154217, 2.8142531243329643, 5.347678752303554, 3.236628762987552, 5.377074226549635, 5.634096535101808, 13.405988675235129]), 
    ('opencountry_053', [10.622402335214636, 0.73712158203125, 1.3175048828125, 5.876377140065916, 5.347678752303554, 3.1134033203125, 6.11476575647307, 1.97711181640625, 13.144871284931902]),
    ('opencountry_123', [10.737785768990813, 3.01690673828125, 3.0810546875, 5.560564920669245, 3.236628762987552, 3.1134033203125, 5.71620618616057, 3.09417724609375, 13.597874214619402]), 
    ('palace_019', [10.566917715980832, 5.890665007775154, 6.634500456993904, 3.7392389463104037, 5.377074226549635, 6.11476575647307, 5.71620618616057, 6.493675414476205, 12.731745772059295]), 
    ('volcano_010', [10.819389772897063, 1.294677734375, 0.78460693359375, 5.709877257908828, 5.634096535101808, 1.97711181640625, 3.09417724609375, 6.493675414476205, 13.90083238519232]),
    ('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232])]

【问题讨论】:

  • 这是一个非常令人困惑的描述...另外,您的示例还不清楚...您是否希望samples 具有多个元素?和distances一样吗?为什么它们都只有 1 个元素?
  • 这只是一种情况......实际上这些列表中会有更多元素
  • 在这些情况下应该如何表现?为什么距离是list?这将使这个效率低下。我认为distances 实际上应该是dict... 元组中的第一个元素,例如'waterfall03' 是独一无二的吗?
  • 好吧,@juanpa.arrivillaga...我已经用更多示例编辑了内容

标签: python filter tuples list-comprehension nested-lists


【解决方案1】:

所以,如果您有以下情况:

distances = [
   ('highway_bost321', [0.0, 10.174343253183386, 10.947746706490813, 7.187637514988234, 7.660483562939873, 10.622402335214636, 10.737785768990813, 10.566917715980832, 10.819389772897063, 12.03400784892136]),
   ('mountain_0871', [10.947746706490813, 0.83758544921875, 0.0, 5.838234191502578, 5.363256367154217, 1.3175048828125, 3.0810546875, 6.634500456993904, 0.78460693359375, 13.91981431878607]),
   ('opencountry_043', [7.660483562939873, 4.668136048210366, 5.363256367154217, 2.8142531243329643, 0.0, 5.347678752303554, 3.236628762987552, 5.377074226549635, 5.634096535101808, 13.405988675235129]),
   ('opencountry_053', [10.622402335214636, 0.73712158203125, 1.3175048828125, 5.876377140065916, 5.347678752303554, 0.0, 3.1134033203125, 6.11476575647307, 1.97711181640625, 13.144871284931902]),
   ('opencountry_123', [10.737785768990813, 3.01690673828125, 3.0810546875, 5.560564920669245, 3.236628762987552, 3.1134033203125, 0.0, 5.71620618616057, 3.09417724609375, 13.597874214619402]),
   ('palace_019', [10.566917715980832, 5.890665007775154, 6.634500456993904, 3.7392389463104037, 5.377074226549635, 6.11476575647307, 5.71620618616057, 0.0, 6.493675414476205, 12.731745772059295]),
   ('volcano_010', [10.819389772897063, 1.294677734375, 0.78460693359375, 5.709877257908828, 5.634096535101808, 1.97711181640625, 3.09417724609375, 6.493675414476205, 0.0, 13.90083238519232]),
   ('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232, 0.0])
]

sample = [
     ('highway_bost321', 0),
     ('mountain_0871', 2),
     ('opencountry_043', 4),
     ('opencountry_053', 5),
     ('opencountry_123', 6),
     ('palace_019', 7),
     ('volcano_010', 8),
     ('waterfall03', 9)
]

然后你可以使用类似的东西:

result = [
    (k, vs[:index] + vs[index+1:]) for (key, index) in samples 
    for k, vs in distances if k == key
]

这让你:

[('highway_bost321', [10.174343253183386, 10.947746706490813, 7.187637514988234, 7.660483562939873, 10.622402335214636, 10.737785768990813, 10.566917715980832, 10.819389772897063, 12.03400784892136]),
 ('mountain_0871', [10.947746706490813, 0.83758544921875, 5.838234191502578, 5.363256367154217, 1.3175048828125, 3.0810546875, 6.634500456993904, 0.78460693359375, 13.91981431878607]),
 ('opencountry_043', [7.660483562939873, 4.668136048210366, 5.363256367154217, 2.8142531243329643, 5.347678752303554, 3.236628762987552, 5.377074226549635, 5.634096535101808, 13.405988675235129]),
 ('opencountry_053', [10.622402335214636, 0.73712158203125, 1.3175048828125, 5.876377140065916, 5.347678752303554, 3.1134033203125, 6.11476575647307, 1.97711181640625, 13.144871284931902]),
 ('opencountry_123', [10.737785768990813, 3.01690673828125, 3.0810546875, 5.560564920669245, 3.236628762987552, 3.1134033203125, 5.71620618616057, 3.09417724609375, 13.597874214619402]),
 ('palace_019', [10.566917715980832, 5.890665007775154, 6.634500456993904, 3.7392389463104037, 5.377074226549635, 6.11476575647307, 5.71620618616057, 6.493675414476205, 12.731745772059295]),
 ('volcano_010', [10.819389772897063, 1.294677734375, 0.78460693359375, 5.709877257908828, 5.634096535101808, 1.97711181640625, 3.09417724609375, 6.493675414476205, 13.90083238519232]),
 ('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232])]

但这是非常低效的。这将是多项式时间。注意内部循环,k, vs in distances if k == key,它非常浪费。

相反,距离应该是一个字典,

distances = dict(distances)

那么你可以这样做:

{key: distances[key][:index] + distances[key][index+1:] for key, index in samples}

【讨论】:

  • 使用dict 绝对是正确的选择。如果 OP 真的需要的话,很容易转换回元组列表......
  • @Nick 是的,确实,我认为值得转换
  • 我唯一的问题是for key, index in sample: del distances[key][index] 是否可能比您使用的理解更有效
  • @Nick 好吧,它不会是一样的。上面的方法创建了一个新列表,您提出的改变了现有列表,两种方法的时间复杂度相同,但some_list.pop(index)del some_list[index] 可能会更快
  • 同意突变,但 OPs 问题表明输出与输入在同一个变量中......我只是建议(如您同意)delpop 会比添加列表的两个部分更快。
【解决方案2】:

因为在您的输出中您被重新分配了distances 变量,我认为您可以从内部列表中弹出元素:

def remove_samples_in_distances(samples, distances):
    for sample, index in samples:
        for name, list_of_distances in distances:
             if sample == name:
                 list_of_distances.pop(index)

用你的测试用例运行它:

samples = [('waterfall03', 9)] 
distances = [('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232, 0.0])]
remove_samples_in_distances(samples, distances)
print(distances == [('waterfall03', [12.03400784892136, 13.17207261956732, 13.91981431878607, 13.095577523116825, 13.405988675235129, 13.144871284931902, 13.597874214619402, 12.731745772059295, 13.90083238519232])])
# output: True

【讨论】:

  • 如果改变列表不是问题,我会说这实际上更干净,只是不是try-except-pass
  • @juanpa.arrivillaga 我把它删了,让代码更干净,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
  • 2020-05-08
相关资源
最近更新 更多