我有两个列表,我想将它们相互映射,但是一个列表包含多个元素。所以我将它们压缩在一起,但它无法正常工作。
列表如下所示:
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
因此BAR
和BAO
未正确映射。
答案 0 :(得分:5)
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']
答案 1 :(得分:2)
最后试试这个:
a = zip(dev2, mod1)
for it, key in a:
words = key.split(',')
for word in words:
print it + '.' + word
答案 2 :(得分:1)
迭代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
:更新解决方案时要求它不需要所有组合,但需要使用a映射b中的元素。
此处,如果您需要唯一的映射,我使用的是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'}
答案 3 :(得分:1)
这是你要注意的吗?
>>> [[(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
答案 4 :(得分:1)
使用join
和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(',')]
(假设a和b的长度相同)
{{1}}
(这似乎比使用zip 花费更少的时间)
答案 5 :(得分:0)
其他答案忽略了您正在阅读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))