【问题标题】:how to merge or join lists and match records in python如何在python中合并或加入列表并匹配记录
【发布时间】:2018-01-08 19:24:32
【问题描述】:

我进行了搜索,但找不到足够接近的东西。

考虑这 3 个或更多包含文件名或任何其他对象的列表 - 在特定目录中找到的列表(相关):

list1 = ['c:\\temp\\file1.txt', 'c:\\temp\\file2.txt', 'c:\\temp\\file3.txt']
list2 = ['d:\\myfiles\\file1.txt', 'd:\\myfiles\\file2.tx', 'd:\\myfiles\\file4.txt']
list3 = ['d:\\backup\\file2.txt', 'd:\\backup\\file3.txt', 'd:\\backup\\file4.txt']

我想要获得的是一个包含三列的表格(可以是 excel、管道分隔的 txt 或类似的),其中包含三列:

column1 (c:\\temp) | column2 (d:\\myfiles) | column3 (d:\\backup)
------------------------------------------------------------------
file1.txt          | file1.txt             | <blank>
file2.txt          | file2.txt             | file2.txt
file3.txt          | <blank>               | file3.txt
<blank>            | file4.txt             | file4.txt

我有列表,但我不知道有什么函数或方法可以按照上面提供的方式对列表进行排序。 Python 2.7 - 我正在使用。

欢迎任何想法。

-地理

【问题讨论】:

  • 列表是否按文件名排序?
  • 那是你要求写的相当多的代码......
  • 请注意右侧先前答案的“相关”链接 - 它们都有 4 位数范围内的赞成票(很少看到)。其中一个只需要工作......
  • 不 - 我没有要求提供代码(也许我没有说清楚:( ) - 只是可以使用的结构的想法。我在精神上坚持使用列表,但作为其他人建议也许字典可能会更好。我实际上可以通过将所有项目放在一起来做到这一点(排序,抓取最大的列表,然后在找到值并继续前进时附加/连接......但它可能需要一个每个列表的迭代,但它似乎不够优雅。

标签: python arrays list


【解决方案1】:

对于您正在解决的问题,字典不是更好的数据结构吗?首先,让我们将您的数据转换为字典:

collections = [list1, list2, list3]
files = {'\\'.join(collection[0].split('\\')[:-1]): [item.split('\\')[-1] for item in collection] for collection in collections}

我知道这是一个很复杂的理解,但它会给你一本很好的字典:

{'c:\\temp': ['file1.txt', 'file2.txt', 'file3.txt'], 'd:\\myfiles': ['file1.txt', 'file2.tx', 'file4.txt'], 'd:\\backup': ['file2.txt', 'file3.txt', 'file4.txt']}

现在,要以您想要的方式显示文件,我们可以简单地遍历键,然后遍历字典的值:

# Headers
for key in files.keys():
    print("%-15s" % key, end="")
print("\n" + "="*44)

#Values
size = max(len(val) for val in files.values())
for i in range(size):
    for path in files:
        name =  "file%s.txt" % str(i+1)
        if name in files[path]:
           print("%-15s" % name, end="")
        else:
            print("%-15s" % "<blank>", end="")
    print()

输出如你所愿:

c:\temp        d:\myfiles     d:\backup
============================================
file1.txt      file1.txt      <blank>        
file2.txt      <blank>        file2.txt      
file3.txt      <blank>        file3.txt 

注意:This may only work for monospaced fonts.

【讨论】:

  • 感谢您的所有想法。只是我实际上只停留在“排序部分”。我也在做一些不仅仅是 filex 的东西,但文件名绝对是恒定的——如果它存在的话。我将回到相关问题(感谢洛根)的建议。
  • @GeoDerthal 好的。你试过运行我的代码吗?有效吗?
  • 还没有。感谢您的解决方案;我认为通过一些变化,我可能很快就能得到一些工作。
【解决方案2】:

我同意 Sam 的观点,第一步是将您的列表转换为列表字典。

from collections import defaultdict

flattened_list = [s for sub in [list1, list2, list3] for s in sub]
tracker = defaultdict(list)

for path in flattened_list:
    dirname, _, basename = path.rpartition('\\')
    tracker[dirname].append(basename)

# {'c:\\temp':    ['file1.txt', 'file2.txt', 'file3.txt'], 
#  'd:\\myfiles': ['file1.txt', 'file2.txt', 'file4.txt'], 
#  'd:\\backup':  ['file2.txt', 'file3.txt', 'file4.txt']}

从这里开始,将这些数据转换为列数据列表或行数据列表非常简单。

dirnames = sorted(tracker)
basenames = sorted(set(sum(tracker.values(), []))) # a set of all file names

# constructs a list for each directory, filling in empty slots with '<blank>'
files = [[b if b in tracker[d] else '<blank>' for b in basenames] for d in dirnames]

column_output = [[d] + f for d, f in zip(dirnames, files)]
# [['c:\\temp',    'file1.txt', 'file2.txt', 'file3.txt', '<blank>'], 
#  ['d:\\myfiles', 'file1.txt', 'file2.txt', '<blank>',   'file4.txt'],
#  ['d:\\backup',  '<blank>',   'file2.txt', 'file3.txt', 'file4.txt']]

row_output = zip(*column_output)
# [('c:\\temp',  'd:\\backup', 'd:\\myfiles'), 
#  ('file1.txt', '<blank>',    'file1.txt'), 
#  ('file2.txt', 'file2.txt',  'file2.txt'), 
#  ('file3.txt', 'file3.txt',  '<blank>'), 
#  ('<blank>',   'file4.txt',  'file4.txt')]

以您想要的方式打印这些或将它们写入 Excel 文件是另一个问题,但应该很容易。

【讨论】:

  • 谢谢!这就是我一直坚持的……出于某种原因,我一直在“列表”模式下思考。字典是正确的结构;你是对的,导出到 excel 或文本很容易——我已经有一个例程来做到这一点。问候!谢谢大家:)
猜你喜欢
  • 2016-10-11
  • 2018-07-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 2022-11-20
  • 2019-08-10
  • 1970-01-01
相关资源
最近更新 更多