【问题标题】:Mapping elements of one list multiple times to elements of a second list将一个列表的元素多次映射到第二个列表的元素
【发布时间】:2017-07-22 23:08:36
【问题描述】:

我有两个列表,我想将它们相互映射,但一个列表包含超过 1 个元素。所以我把它们压缩在一起,但它不能正常工作。

列表如下所示:

a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
b = ['TEM', 'BAR', 'BAO', 'RAI']

我正在努力实现这一目标:

TEM.TEMP
BAR.TEMP
BAR.PRE
BAO.TEMP
BAO.HUM
BAO.RAN
RAI.HUM

我想将b 的每一项映射到a,但是在a 中有更多的值被, 分隔

我的代码如下:

import csv


mod1 = []
dev2 = []
d = {}
with open('/home/robi/Desktop/rob/device.csv', 'rb') as f:
    next(f, None)
    reader = csv.reader(f, delimiter=';')
    for row in reader:
        mod1.append(row[0])
        dev2.append(row[1])

    a = zip(dev2, mod1)
    for it, key in a:
        print it + '.' + key

但我得到这样的结果:

BAO.TEMP,HUM,RAN
BAR.TEMP,PRE
RAI.HUM

所以BARBAO 没有正确映射。

【问题讨论】:

  • 否定但为什么呢?我很高兴听到,所以以后我在提问时必须小心
  • 您的代码抛出错误IndentationError: expected an indented block,因此输出不能来自您在此处提供的代码,原样。你在发帖时应该更加小心,你应该忽略你的感激之情等:阅读this help page的最后一段并将其应用于你的帖子和cmets。
  • @Anthon 我将遵循这些准则。我在代码中更正了我的缩进,我阅读了这一段,我将按照描述进行操作。
  • 无缘无故否决答案是不好的。至少应该给出一些正当的理由。 .
  • 将鼠标悬停在向下箭头上方时会显示原因。故意让您在投反对票时不必发表评论或类似内容。对您的问题投反对票的人实际上看到您的评论的可能性很小。正如我所评论的,我是唯一一个收到您的消息通知的人。没有其他人得到通知,当然也没有投票者。

标签: python csv tuples


【解决方案1】:

zip 适用于list 索引,因此它无法根据您的标准识别特定项目中是否有更多项目。您必须进行一些后处理来构建最终列表,即用逗号将第一个列表中的元素拆分,然后将每个元素与第二个列表中的元素组合。比如:

a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
b = ['TEM', 'BAR', 'BAO', 'RAI']

c = ["%s.%s"%(e[1],i) for e in zip(a, b) for i in e[0].split(",")]
# ['TEM.TEMP', 'BAR.TEMP', 'BAR.PRE', 'BAO.TEMP', 'BAO.HUM', 'BAO.RAN', 'RAI.HUM']

【讨论】:

  • 感谢 zwer 的帮助。你的代码工作正常,但 JRG 对我来说看起来很简单,它也可以工作。我不能接受两个答案,否则我也会接受你的一个。 .但非常感谢您的帮助。
  • @robbin - 除了他的答案不正确,至少只要您的问题是I want to map every item of b to a - 他的代码将为您提供ab 的组合列表,其中包括BAR.RAN 之类的东西不在您想要的输出列表中。如果您想要 ab 中的所有项目组合,您应该更新您的问题以反映这一点。
  • 是的,我想将 b 的每个项目映射到 a。 .wait 我会再检查一次。抱歉,是我的错。 .
  • 你是对的。这是我的错。他的代码给了我组合。 .我会向他道歉,并会接受你的回答,因为我猜你是第二个回答,你的解决方案很好。
  • '.'.join((e[1],i))对我来说比"%s.%s"%(e[1],i)更具可读性
【解决方案2】:

最后试试这个:

a = zip(dev2, mod1)
for it, key in a:
    words = key.split(',')
    for word in words:
        print it + '.' + word

【讨论】:

    【解决方案3】:

    使用list comprehensionjoin假设 a 和 b 的长度相同

    a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
    b = ['TEM', 'BAR', 'BAO', 'RAI']
    length = len(a)
    
    result = ['.'.join((b[index],sub_item) ) 
                  for index in range(length) for sub_item in a[index].split(',')]
    

    (这似乎比使用 zip 花费的时间少一点)

    【讨论】:

      【解决方案4】:

      这是你要找的吗?

       >>> [[(b[i], x) for x in a[i].split(',')] for i in range(len(a))]
       [[('TEM', 'TEMP')],
       [('BAR', 'TEMP'), ('BAR', 'PRE')],
       [('BAO', 'TEMP'), ('BAO', 'HUM'), ('BAO', 'RAN')],
       [('RAI', 'HUM')]]
      

      尽管我的回答对你来说不够好,但这里有一个解决方案,可以将它放入你想要的字符串中。

      >>> reduce(lambda x, y: x + y, [['.'.join((b[i], x)) for x in a[i].split(',')] for i in range(len(a))])
      ['TEM.TEMP',
       'BAR.TEMP',
       'BAR.PRE',
       'BAO.TEMP',
       'BAO.HUM',
       'BAO.RAN',
       'RAI.HUM']
      

      可悲的是,没有人会看到这个,但至少 会知道我有多棒...... /s

      【讨论】:

        【解决方案5】:

        遍历b 中的项目,因为它在单个键中没有多个键,然后遍历a 中的项目并检查它是否包含分隔符, 并对其进行拆分。

        如果需要,我还添加了代码以使用 set 进行唯一组合。

        def getCombinations(a, b):
            combinations = []
            for bitem in b:
                for aitem in a:
                    if ("," in aitem):
                        for aitemInner in aitem.split(","):
                            combinations.append(bitem + "." + aitemInner)
                    else:
                        combinations.append(bitem + "." + aitem)
            ## Optional : if you want unique combinations of B and A
            unique = set(combinations)
            return unique
        
        a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
        b = ['TEM', 'BAR', 'BAO', 'RAI']
        combinations = getCombinations(a, b)
        print("Keys in a          : " + str(len(a)))
        print("Keys in b          : " + str(len(b)))
        print("Total Combinations : " + str(len(combinations)))
        print(combinations)
        

        样品运行

        Keys in a          : 4
        Keys in b          : 4
        Total Combinations : 16
        {'TEM.HUM', 'RAI.HUM', 'BAR.PRE', 'BAO.HUM', 'TEM.PRE', 'RAI.RAN', 'RAI.TEMP', 'BAR.HUM', 'RAI.PRE', 'BAO.PRE', 'BAR.RAN', 'BAO.RAN', 'TEM.TEMP', 'TEM.RAN', 'BAO.TEMP', 'BAR.TEMP'}
        

        EDIT :更新解决方案,要求它不需要所有组合,但需要将 b 中的元素映射到 a。

        在这里,如果您需要唯一的映射,我也使用set,否则您可以从get1To1Mapping() 方法返回组合。

        NOTE:我得到了列表的最小大小,并且只给出了没有的映射。根据最小列表的元素,以避免异常。

        def get1To1Mapping(a, b):
            combinations = []
            ## some might argue to iterate over len(b) but i would go for minimum
            ## of both the list to avoid exception
            for index in range(min(len(a), len(b))):
                if ("," in a[index]):
                    for aitem in a[index].split(","):
                        combinations.append(b[index] + "." + aitem)
                else:
                    combinations.append(b[index] + "." + a[index])
            ## optional : if you want just unique mappings
            unique = set(combinations)
            return unique
        
        a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
        b = ['TEM', 'BAR', 'BAO', 'RAI']
        combinations = get1To1Mapping(a, b)
        print("Keys in a          : " + str(len(a)))
        print("Keys in b          : " + str(len(b)))
        print("Total Combinations : " + str(len(combinations)))
        print(combinations)
        

        样品运行

        Keys in a          : 4
        Keys in b          : 4
        Total Combinations : 7
        {'BAR.PRE', 'RAI.HUM', 'TEM.TEMP', 'BAO.TEMP', 'BAO.HUM', 'BAO.RAN', 'BAR.TEMP'}
        

        【讨论】:

        • np,很高兴为您提供帮助
        • 拆分前无需检查。
        • @JRG 接受我的道歉,我没有正确检查。你的代码有一个问题,它给了我组合。但我只是想将b中的每个元素映射到a。 .我会接受zwer的回答。我很抱歉,这是我的错误。希望你能理解
        • 不用担心接受答案,我想更正我的解决方案,以便将来参考。你能解释一下将b中的元素映射到a是什么意思吗,你有预期的输出吗?
        • 我已经用您需要的解决方案更新了我的解决方案,以供将来参考。
        【解决方案6】:

        其他答案忽略了您正在阅读 csv 文件。您可以在阅读文件后立即以更合适的结构排列数据。将您的此类列表压缩在一起表明数据可以以更好的方式结构化 - 字典。

        您可以避免创建两个列表,而是立即将元素添加到字典中(如果必须对元素进行排序,请使用 collections.OrderedDict):

        dictio = {}
        
        with open('csv_file.csv') as f:
            next(f, None)
            reader = csv.reader(f, delimiter=';')
            for mod1, dev2 in reader:
                dictio[dev2] = mod1.split(',')
        
        for key, value in dictio.items():
            for word in value:
                print('{}.{}'.format(key, word))
        

        【讨论】:

        • 我仍然不确定您为什么要打印这些字符串。更多背景信息会很好。
        • 感谢您的帮助,实际上我将编写一些代码来执行某些任务,为此我需要有效地组合这两个列表并将它们存储起来,以便我可以对其执行一些操作。跨度>
        • 什么样的操作?
        • 我有多个 csv 文件。最后我必须准备 yaml 配置文件。 .为此,首先我必须对某些csv文件列执行一些操作才能以第一范式(1NF)获得它们。之后,我将通过推导一些逻辑来自动执行此任务。 ....所以某些列包含更多用逗号分隔的值,因此我必须将它们转换为 1NF 形式,这就是为什么我在我的问题中要求在此处进行映射。 .
        • 我不确定是否可以帮助你,但我建议创建一个正确且完整(可执行)的示例,然后将其发布到codereview.stackexchange.com 以获取有关优化可读性、代码结构的提示或性能。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-25
        • 2019-05-17
        • 1970-01-01
        • 1970-01-01
        • 2019-06-27
        相关资源
        最近更新 更多