【问题标题】:Iterating through 2 dimensional lists in 1 line在 1 行中迭代二维列表
【发布时间】:2019-01-12 13:13:40
【问题描述】:

对于 2D 列表 [["bacon", "banana"], ["ham", "salami", "cheese"]] 我想迭代为 "bacon",然后是 "banana",然后是 "ham "等。

sandwiches = [["bacon", "banana"], ["ham", "salami", "cheese"]]
preferences = ["bacon", 5, "ham", -2, "salami", 1]

在三明治数组中,有 2 个三明治,培根+香蕉和火腿+意大利腊肠+奶酪。我想通过做这样的事情来知道每个三明治的分数(不起作用,但显示了我想做的事情):

sandwichscores = [0 for i in sandwiches]
sandwichscores = [+preferences[preferences.index(j)+1] for j in i in sandwiches if
j in preferences]

当然对于 j in i in 三明治是行不通的。我试过弄乱fors和ins的顺序,但没有得到任何结果。这怎么可能?

例如,我想要的输出是:

sandwichscores = [5, -1]

因为成分在第一个三明治中的综合得分为 5,在第二个三明治中为 -1。不在偏好中的成分会被忽略。

【问题讨论】:

  • 您最好根据自己的喜好使用字典:preferences = { 'bacon' : 5, 'ham' : -2 }
  • 不清楚你在问什么。在迭代中“培根”和“香蕉”之后是什么?是“火腿”“意大利腊肠”“奶酪”还是别的什么?也不清楚你想要什么输出。
  • 顺序无关紧要,只要每个元素迭代一次即可。
  • 其实很抱歉,我希望能澄清我想要的订单的歧义。
  • 明确地说,您要生成培根/火腿、培根/意大利腊肠、培根/奶酪、香蕉/火腿、香蕉/意大利腊肠、香蕉/奶酪的分数吗?

标签: python arrays list for-loop multidimensional-array


【解决方案1】:

这是一个可以满足您的需求的单线;我将您的偏好列表转换为a dictionary,因为那是much more suitable data structure when you are storing key/value pairs

sandwiches = [["bacon", "banana"], ["ham", "salami", "cheese"]]
prefs = {"bacon": 5, "ham": -2, "salami": 1}

scores = [ [ ", ".join(i), sum( prefs[j] for j in i if j in prefs) ] for i in sandwiches ]
print(scores)

输出:

[['bacon, banana', 5], ['ham, salami, cheese', -1]]

该解决方案使用sum 将三明治成分的值相加,根据该成分是否出现在prefs 中进行过滤。

您可以更改输出格式以删除成分列表,并通过更改 [ ", ".join(i), sum( prefs[j] for j in i if j in prefs) ] 部分来输出分数。我会认为知道哪个三明治得到哪个分数很重要,但谁知道呢!

【讨论】:

  • dict.get(key, 0)prefs[j] for ... if j in prefs
  • 它是我用的 ;)
  • @PatrickArtner 我希望 OP 能够从我们的两个答案中获得灵感,并进一步研究字典的惊人力量。 ;D
【解决方案2】:

我认为这是您要使用的逻辑,解压缩到嵌套的 for 循环中:

for i, sandwich in enumerate(sandwiches):
    for filling in sandwich:
        if filling in preferences:
            sandwichscores[i] += preferences[preferences.index(filling)+1]

print(sandwichscores)
>>> [5, -1]

正如我警告外星人所说,如果你使用字典来得分,逻辑会简单得多:

preferences = {'bacon':5,'ham':-2,'salami':1}

#...

for i, sandwich in enumerate(sandwiches):
    for filling in sandwich:
        sandwichscores[i] += preferences.get(filling, 0)

【讨论】:

  • 我喜欢简短。
【解决方案3】:

这里还有另外一种方法,虽然我把preferences的结构改成了字典,这样更实用也更容易使用:

sandwiches = [["bacon", "banana"], ["ham", "salami", "cheese"]]
preferences = {"bacon" : 5, "ham" : -2, "salami" : 1}

scores = [sum(preferences.get(ingredient,0) for ingredient in sandwich) for sandwich in sandwiches]
print(scores)

输出:

[5, -1]

【讨论】:

    【解决方案4】:

    这是一个使用groupby的班轮:

    from itertools import groupby
    
    sandwiches = [["bacon", "banana"], ["ham", "salami", "cheese"]]
    preferences = ["salami", 999, "bacon", 5, "ham", -2, "banana", 1000]
    
    l = [(v, sum(i[-1] for i in g)) for v, g in groupby(((sandwich, preferences[preferences.index(p)+1]) for sandwich, prefs in zip(sandwiches, [preferences[::2]] * len(sandwiches)) for p in prefs if p in sandwich), key=lambda v: v[0])]
    print(l)
    

    打印:

    [(['bacon', 'banana'], 1005), (['ham', 'salami', 'cheese'], 997)]
    

    对于三明治['bacon', 'banana']:培根有 5,香蕉有 1000,三明治得分是 1005

    三明治['ham', 'salami', 'cheese']:火腿-2,意大利腊肠999,三明治997

    【讨论】:

      【解决方案5】:

      我会使用dictionary 进行分数查找——它是用于查找的指定数据结构。

      您可以从 preferences 的表示转到具有 dict-comprehension 的字典:

      preferences = ["bacon", 5, "ham", -2, "salami", 1]
      
      prefs = {k:v for k,v in zip(preferences[::2],preferences[1::2])} # dict-comprehension
      

      这使用zip() 将从0 ["bacon","ham","salami"] 开始的每个第二个元素连接到从1 [5,-2,1] 开始的每个第二个元素,从而生成(("bacon,5),("ham",-2),("salami",1)) 的zip 生成器。

      然后将 zip-generator-result 分解为创建 dict 的 key:value 对。


      除此之外,您可以像这样计算总和:

      sandwiches = [["bacon", "banana"], ["ham", "salami", "cheese"]]
      prefs = {"bacon": 5, "ham": -2, "salami": 1}
      
      score = [ (sandw, sum( prefs.get(ingred,0) 
                             for ingred in sandw)) 
                for sandw in sandwiches ]
      
      print(score) 
      

      score 总结了您定义的每个绞盘机的每个成分得分。如果没有找到成分,则添加 0。

      输出是三明治及其分数的元组:

       [(['bacon', 'banana'], 5), (['ham', 'salami', 'cheese'], -1)]
      

      【讨论】:

      • 如何从文本文件生成字典?我目前有:
      • preferences = [line.translate({ord(c): "" for c in ""}).translate({ord(c): " " for c in ","})。 split() for line in file1] (去掉空格和逗号,制作一个二维的首选项列表),然后是preferences = sum(preferences, []) (将二维数组变成一维数组)
      猜你喜欢
      • 2017-09-15
      • 2013-05-09
      • 1970-01-01
      • 2018-12-01
      • 2022-11-25
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多