字典是否是此信息的良好数据结构?

时间:2017-04-18 14:58:20

标签: python python-3.x dictionary

我对python并不是特别擅长,而且我在尝试解决问题时遇到了一些问题。我想要做的是以下几点:

我有一个大文本文件,每行有三个关键数据,这里有大约120万个图像及其相关数据。例如:

123.jpg     | (200 x 200)   | /dir/123.jpg
456.jpg     | (200 x 200)   | /dir/456.jpg
123_0.jpg   | (1080 x 1080)   | /dir/123_0.jpg
456_001.jpg | (2080 x 2080) | /dir/456_001.jpg
596.jpg     | (200 x 480)   | /dir/593.jpg

从上面的示例中可以看出,一些图像具有相同的名称,并标记了一些额外的位。我想要做的是能够找到图像ID,即123,搜索文件并只获取具有最大分辨率的文件并将其输出到新文件。即对于图像ID 123,最终在输出文件中的文件将是123_0.jpg的位置。

我的方法是创建字典数据类型。

with open('test.txt', 'r') as data:
    for line in data:
        fileValue = line.split(' | ')
        data = {'Image Name':fileValue[0],
                'Resolution':fileValue[1],
                'Location':fileValue[2]
                }

然而,我似乎无法找出/访问除最后一个值之外的dict中的任何值。很明显,我误解了数据类型以及如何使用它,但是当我运行类似print(data.values())的内容时,我只是从test.txt读取最后一行。

我的问题是如何访问每个值,或者在字典中存储多个值来做我想做的事情?我在这里滥用词典,即我应该使用词典词典吗?

3 个答案:

答案 0 :(得分:2)

字典将是一个很好的整体数据结构,因为它可以非常快速地通过id查找数据。您也可以将与每个id相关联的信息的“位”存储到字典中。

import os
from pprint import pprint
img_dict = {}

with open('img_test_data.txt', 'r') as data_file:
    for line in data_file:
        filename, res, loc = [item.strip() for item in line.split(' | ')]
        id = os.path.splitext(filename)[0]  # remove extension
        img_dict[id] = {'Image Name': filename, 'Resolution': res, 'Location': loc}

pprint(img_dict)

输出:

{'123': {'Image Name': '123.jpg',
         'Location': '/dir/123.jpg',
         'Resolution': '(200 x 200)'},
 '123_0': {'Image Name': '123_0.jpg',
           'Location': '/dir/123_0.jpg',
           'Resolution': '(1080 x 1080)'},
 '456': {'Image Name': '456.jpg',
         'Location': '/dir/456.jpg',
         'Resolution': '(200 x 200)'},
 '456_001': {'Image Name': '456_001.jpg',
             'Location': '/dir/456_001.jpg',
             'Resolution': '(2080 x 2080)'},
 '596': {'Image Name': '596.jpg',
         'Location': '/dir/593.jpg',
         'Resolution': '(200 x 480)'}}

这将使访问它们相当容易,虽然有点冗长。

print(img_dict['456']['Image Name'])  # -> 456.jpg
print(img_dict['456']['Resolution'])  # -> (200 x 200)
print(img_dict['456']['Location'])    # -> /dir/456.jpg

有一些方法可以使信息的访问更加简洁。您可以创建collections.namedtuple而不是子词典。另一种可能性是自定义类的实例。这些中的任何一个都会将上述内容简化为以下内容:

print(img_dict['456'].image_name)  # -> 456.jpg
print(img_dict['456'].resolution)  # -> (200 x 200)
print(img_dict['456'].location)    # -> /dir/456.jpg

以下是创建包含namedtuple个实例而非子词典的字典的内容:

import os
from collections import namedtuple

MovieInfo = namedtuple('MovieInfo', 'image_name, resolution, location')
img_dict = {}

with open('img_test_data.txt', 'r') as data_file:
    for line in data_file:
        filename, res, loc = [item.strip() for item in line.split(' | ')]
        id = os.path.splitext(filename)[0]  # remove extension
        img_dict[id] = MovieInfo(filename, res, loc)

导致img_dict填写如下:

{'123': MovieInfo(image_name='123.jpg', resolution='(200 x 200)', location='/dir/123.jpg'),
 '123_0': MovieInfo(image_name='123_0.jpg', resolution='(1080 x 1080)', location='/dir/123_0.jpg'),
 '456': MovieInfo(image_name='456.jpg', resolution='(200 x 200)', location='/dir/456.jpg'),
 '456_001': MovieInfo(image_name='456_001.jpg', resolution='(2080 x 2080)', location='/dir/456_001.jpg'),
 '596': MovieInfo(image_name='596.jpg', resolution='(200 x 480)', location='/dir/593.jpg')}

答案 1 :(得分:1)

我认为你需要的是list dict s:

data = []
with open('test.txt', 'r') as data:
    for line in data:
        fileValue = line.split(' | ')
        data.append({'Image Name':fileValue[0],
                'Resolution':fileValue[1],
                'Location':fileValue[2]
                })

现在,您可以通过索引访问从行中提取的各个记录:

record = data[index]

并使用您的密钥访问字段:

print record['Image Name']

答案 2 :(得分:1)

我最明显的问题之一就是你已经在正在打开的文件范围内有一个名为data的变量,当你持有你的dictionary时,你试图将其重置为list文件信息。

with-as语句之外声明dictionaries是一种很好的方式,可以将fileData = [] with open('test.txt', 'r') as data: for line in data: components = list(map(lambda s: s.strip(), line.split('|'))) fileData.append({'Image Name': components[0], 'Resolution': components[1], 'Location': components[2] }) 包含每个信息的信息放入其中并保存以供日后使用。

components = list(map(lambda s: s.strip(), line.split('|')))

list只是为文件中的每一行生成|,其中值由[ {'Location': '/dir/123.jpg', 'Image Name': '123.jpg', 'Resolution': '(200 x 200)'}, {'Location': '/dir/456.jpg', 'Image Name': '456.jpg', 'Resolution': '(200 x 200)'}, {'Location': '/dir/123_0.jpg', 'Image Name': '123_0.jpg', 'Resolution': '(1080 x 1080)'}, {'Location': '/dir/456_001.jpg', 'Image Name': '456_001.jpg', 'Resolution': '(2080 x 2080)'}, {'Location': '/dir/593.jpg', 'Image Name': '596.jpg', 'Resolution': '(200 x 480)'} ] 字符拆分,并且所有空格都被删除。

这将生成一个列表:

test.find_users_in_categories(BIGINT[])