【问题标题】:Why are dictionary values being overriden at the end of this loop?为什么在此循环结束时会覆盖字典值?
【发布时间】:2014-01-25 03:35:11
【问题描述】:

我有一本名为停靠点的公共交通站点字典。我想复制那些正在转移的那些(有不止一条线),这样每条额外的线都有一个重复的停靠点。我最初将这些重复项存储在一个称为重复项的字典中。但是,在我为每个重复站点分配适当行的名称后,它们都会被原始站点的原始行列表中的最后一行覆盖。所以我最终得到了一堆重复的站点,所有站点都使用同一行,而不是每行一个站点。是什么覆盖了这些价值观?文件 l_stops.csv 位于 Dropboxbpaste

import csv
import random

def stop_coords():
    with open('l_stops.csv', 'rb') as csvfile:
        stop_reader = csv.reader(csvfile, delimiter=',', quotechar='"')
        stops = {}
        for row in stop_reader:
            map_id = row[5]
            lines = set()
            if row[7] == 'true':
                lines.add('Red')
            if row[8] == 'true':
                lines.add('Blue')
            if row[9] == 'true':
                lines.add('Green')
            if row[10] == 'true':
                lines.add('Brown')
            if row[11] == 'true':
                lines.add('Purple')
            if row[13] == 'true':
                lines.add('Yellow')
            if row[14] == 'true':
                lines.add('Pink')
            if row[15] == 'true':
                lines.add('Orange')
            if map_id not in stops:
                stop_name = row[2].partition('(')[0].rstrip(' ')
                lat = float(row[16].lstrip('"(').rpartition(',')[0])
                lng = float(row[16].lstrip('"(').rpartition(',')[2].strip(' )"'))
                stop = {}
                stop['name'] = stop_name
                stop['lat'] = lat
                stop['lng'] = lng
                stop['x'] = lng
                stop['y'] = lat
                stop['lines'] = lines
                stops[map_id] = stop
                stop['duplicateStops'] = []
            elif stops[map_id]['lines'] != lines:
                stops[map_id]['lines'] = stops[map_id]['lines'].union(lines)
        for item in stops:
            stops[item]['lines'] = list(stops[item]['lines'])

        # Add duplicate stops for stops that are transfers (shared by multiple lines)
        duplicates = {} # the dictionary that will hold the duplicates and be added to the stops dictionary after all duplicate stops have been processed
        for item in stops:
            num_lines = len(stops[item]['lines'])
            if num_lines > 1: # if a stop has more than one line
                original_lines = stops[item]['lines']
                stops[item]['lines'] = original_lines[0]
                equivalent_map_ids = [item] # Make a list of different map_ids that represent the same stop (but on different lines). The first map_id in the list will be the "original" one.
                for i in range(num_lines - 1): # for each line after the first one
                    # Create a new map_id and make sure it doesn't conflict with an existing map_id
                    while True:
                        new_map_id = str(random.randint(10000, 99999))
                        if new_map_id not in stops and new_map_id not in duplicates:
                            break
                    duplicates[new_map_id] = stops[item] # duplicate the stop
                    equivalent_map_ids.append(new_map_id) # add the new map_id to the list of equivalent map_ids
                # Set the duplicateStops value of everyone in equivalent_map_ids's to the other stops' map_ids
                # The first map_id in equivalent_map_ids is the original one that's in the stops dictionary, so set its duplicateStops value to the rest of the list
                stops[item]['duplicateStops'] = equivalent_map_ids[1:]

                # For the rest of the map_ids in equivalent_map_ids
                j = 1
                for duplicate_stop in stops[item]['duplicateStops']:
                    duplicates[duplicate_stop]['lines'] = original_lines[j]
                    duplicates[duplicate_stop]['duplicateStops'] = equivalent_map_ids[:j] + equivalent_map_ids[(j + 1):]  # this line also changes stops[item]['duplicateStops'], not sure how
                    j+= 1
                # somehow by this point all duplicates have the same line (the last line in the original 'lines' list)
                for stop in stops[item]['duplicateStops']:
                    print duplicates[stop]['name']
                    print duplicates[stop]['lines']

        for item in duplicates:
            print item
            print duplicates[item]['name']
            print duplicates[item]['lines']
        stops.update(duplicates)
        stops['none'] = {'name' : 'none', 'lat' : 0, 'lng' : 0, 'x' : 0, 'y' : 0, 'lines' : ['none']}

在调试时,我发现重新分配重复项[duplicate_stop]['duplicateStops'] 也会重新分配停止点[item]['duplicateStops']。这怎么可能?重复和停止是两个独立的字典。

【问题讨论】:

    标签: python csv dictionary


    【解决方案1】:

    然后duplicates[duplicate_stop]stops[item]命名 相同 对象- 并且改变 对象,嗯,改变 对象。对象在赋值或用作函数参数时不会自动复制/克隆/复制。

    最有可能出现问题的行

    duplicates[new_map_id] = stops[item] # duplicate the stop
    

    .. 并且评论是错误的,因为没有发生 重复。


    问题Understanding dict.copy() - shallow or deep? 可能有用;至少它展示了如何制作真实的副本。

    【讨论】:

      猜你喜欢
      • 2019-11-24
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      • 2021-01-08
      • 2021-02-07
      • 1970-01-01
      • 2020-09-11
      相关资源
      最近更新 更多