Python 将一个列表的元素多次映射到第二个列表的元素

Python 将一个列表的元素多次映射到第二个列表的元素,python,csv,tuples,Python,Csv,Tuples,我有两个列表,我想将它们相互映射,但一个列表包含多个元素。所以我把它们拉在一起,但它不能正常工作 列表如下所示: a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM'] b = ['TEM', 'BAR', 'BAO', 'RAI'] BAO.TEMP,HUM,RAN BAR.TEMP,PRE RAI.HUM 我正努力做到这一点: TEM.TEMP BAR.TEMP BAR.PRE BAO.TEMP BAO.HUM BAO.RAN RAI.HUM 我

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

列表如下所示:

a = ['TEMP', 'TEMP,PRE', 'TEMP,HUM,RAN', 'HUM']
b = ['TEM', 'BAR', 'BAO', 'RAI']
BAO.TEMP,HUM,RAN
BAR.TEMP,PRE
RAI.HUM
我正努力做到这一点:

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
但我得到的结果如下:

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

因此,
BAR
BAO
没有正确映射。

迭代
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'}
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'}
编辑
:更新解决方案,要求它不需要所有组合,但需要将b中的元素映射到a

这里,我还使用了
set
,如果您需要唯一的映射,那么您可以从
get1To1Mapping()
方法返回组合

注意
:我得到了列表的最小大小,并且只根据最小列表给出了元素数量的映射,以避免异常

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 : 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'}
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'}

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

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']

这就是你要找的吗

 >>> [[(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

在结尾尝试以下方法:

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

使用
列表理解
连接
(假设a和b的长度相同)


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

其他答案忽略了您正在读取的是csv文件。您可以在读取文件后立即以更合适的结构排列数据。将类似于您的列表压缩在一起是一个指标,表明数据可以以更好的方式进行结构化—字典

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



谢谢zwer的帮助。您的代码工作得很好,但JRG one在我看来很简单,而且也可以工作。我不能接受两个答案,否则我也会接受你的一个。但是非常感谢你的帮助。@robbin-除了他的答案不正确之外,至少只要你的问题是
我想把b的每一项都映射到a
-他的代码会给你一个
a
b
的组合列表,其中包括
BAR.RAN
之类的东西,而这不在你想要的输出列表中。如果您想要
a
b
中所有项目的组合,您应该更新您的问题以反映这一点。是的,我想将b的每个项目映射到a。等等,我再查一下。对不起,我弄错了。你说得对。这是我的错。他的密码给了我密码。我会向他道歉并接受你的回答,因为我猜你是第二个回答的人,你的解决方案很好。
。.join((e[1],I))
%s.%(e[1],I)
np更易读,很乐意帮忙在你分手之前不需要检查。@JRG接受我的道歉,我没有正确检查。你的代码有一个问题,它给了我一个组合。但我只是想把b中的每个元素映射到a。我会接受zwer的回答。我很抱歉,这是我的错误。我希望你们能理解,不要担心接受答案,我想更正我的解决方案,以便将来参考。你能解释一下把b中的元素映射到a是什么意思吗?你有预期的输出吗?我已经用你需要的解决方案更新了我的解决方案,仅供将来参考。否定,但为什么呢?。我很乐意听到,因此将来我在提问时必须小心您的代码抛出错误
IndentationError:预期为缩进块
,因此输出不能来自您在此处展示的代码。发帖时你应该更加小心,不要说你很感激,等等:阅读文章的最后一段并将其应用到你的帖子和评论中。@Anthon我将遵循这些指导原则。我更正了代码中的缩进,阅读了这一段,我将按照描述进行操作。没有任何理由地否决答案是不好的。至少应该给出一些合理的理由。将鼠标悬停在向下箭头上方时,将显示原因。这是有意的,当你投否决票时,你不必发表评论或类似的评论。对你的问题投了否决票的人看到你的评论的可能性很小。正如我所评论的,我是唯一一个收到你的消息通知的人。没有其他人得到通知,当然不是下层选民。我仍然不知道你为什么要打印这些字符串。更多的背景信息会很好。谢谢你的帮助,实际上我会写一些代码来执行一些任务,为此,我需要有效地组合这两个列表并存储它们,以便我可以对其执行一些操作。什么样的操作?我有多个csv文件。最后,我必须准备yaml配置文件。为此,首先我必须对csv文件的某些列执行一些操作,以获得第一个标准格式(1NF)的文件。在那之后,我将通过推导一些逻辑来自动完成这项任务。。。。所以某些列包含更多用逗号分隔的值,所以我必须将它们转换成1NF形式,这就是为什么我要求在这里映射