为什么在这个循环结束时字典值被覆盖? [英] Why are dictionary values being overriden at the end of this loop?

查看:184
本文介绍了为什么在这个循环结束时字典值被覆盖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个公共交通站点的词典叫停止。我想复制那些是传输(有多行),以便在这些额外的行的停靠点重复停止。我最初存储这些重复的字典称为duplicateates。但是,在为每个重复停靠点分配相应行的名称后,它们都将被原始停靠点原始列表中的最后一行覆盖。所以我结束了一堆重复停止所有与同一行,而不是一个停止每行。什么是重写这些值?文件l_stops.csv位于 Dropbox bpaste

  import csv 
import random

def stop_coords():
with open('l_stops.csv','rb')as csvfile:
stop_reader = csv.reader(csvfile,delimiter =',',quotechar ='')
stops = {}
for stop_reader:
map_id = row [5]
lines = set b如果row [7] =='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')
如果map_id不在stops中:
stop_name = row [2] .partition('(')[0] .rstrip b $ b lat = float(row [16] .lstrip(''(')。rpartition(',') .rpartition(',')[2] .strip(')'))
stop = {}
stop ['name'] = stop_name
stop ['lat'] = lat
stop ['lng'] = lng
stop ['x'] = lng
stop ['y'] = lat
stop ['lines'] = lines
stop [map_id] = stop
stop ['duplicate_stops'] = []
elif stops [map_id] line'] = stops [map_id] ['lines']。union(lines)
停止中的项目:
stops [item] ['lines'] = list(stops [item] '])

#为转移的停止添加重复停止(由多行共享)
duplicateates = {}#将保存重复的字典,并添加到停止字典所有重复停止已处理
停止中的项目:
num_lines = len(stops [item] ['lines'])
如果num_lines> 1:#如果一个停靠点有多行
original_lines = stops [item] ['lines']
stops [item] ['lines'] = original_lines [0]
equivalent_map_ids = [item]#创建代表同一站点(但在不同的行)的不同map_ids的列表。列表中的第一个map_id将是原始。
for i in range(num_lines - 1):#为第一行之后的每一行
#创建一个新的map_id,并确保它不与现有的map_id冲突
while True:
new_map_id = str(random.randint(10000,99999))
如果new_map_id不在停止,new_map_id不在重复中:
break
duplicateates [new_map_id] = stops [item] #重复停止
equivalent_map_ids.append(new_map_id)#将新的map_id添加到等效map_ids列表
#将equivalent_map_ids中每个人的duplicateStops值设置为其他站点的map_ids
# equals_map_ids中的第一个map_id是停止字典中的原始值,因此将duplicateStops值设置为列表的其余部分
stops [item] ['duplicateStops'] = equivalent_map_ids [1:]

#对于equals_map_ids中的map_ids的其余部分
j = 1
用于stops中的duplicate_stop [item] ['duplicateStops']:
duplicates [duplicate_stop] ['lines'] = original_lines [ j]
重复[duplicate_stop] ['duplicateStops'] = equivalent_map_ids [:j] + equivalent_map_ids [(j + 1):]#这行也改变了停止[item] ['duplicateStops'], b $ b j + = 1
#在某种程度上,所有重复项都有相同的行(原始'行'列表中的最后一行)
停止在停止[item] ['duplicateStops']:
打印副本[stop] ['name']
打印副本[stop] ['lines']

用于重复项目:
打印项目
打印副本[item] ['name']
打印副本[item] ['lines']
stops.update(重复)
stops ['none'] = {'name' :'none','lat':0,'lng':0,'x':0,'y':0,'lines':['none']}



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

解决方案

然后重复[duplicate_stop] 停止[item] 同时 ,好,更改对象。对象不是在作业上自动复制/克隆/复制,或用作函数参数。



有问题的行最有可能

 重复[new_map_id] = stops [item]#重复停止

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






问题理解dict.copy() - 浅或深?可能有用;至少它显示如何做一个真正的副本。


I have a dictionary of public transportation stops called stops. I want to duplicate the ones that are transfers (have more than one line) so that there is a duplicate stop in stops for each of those additional lines. I initially store those duplicates in a dictionary called duplicates. However, after I assign the name of the appropriate line to each duplicate stop, they all gets overriden by the last line in the original stop's original list of lines. So I end up with a bunch of duplicate stops all with the same line instead of one stop for each line. What is overriding these values? The file l_stops.csv is on Dropbox and bpaste.

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

While debugging, I discovered that reassigning duplicates[duplicate_stop]['duplicateStops'] also reassigns the stops[item]['duplicateStops']. How is that possible? duplicates and stops are two separate dictionaries.

解决方案

Then duplicates[duplicate_stop] and stops[item] both name the same object - and mutating the object, well, changes the object. Objects are not automatically copied/cloned/duplicated on an assignment or when used as function arguments.

The problematic line is most likely

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

.. and the comment is wrong because there is no duplication that occurs.


The question Understanding dict.copy() - shallow or deep? may be useful; at the very least it shows how to make a real copy.

这篇关于为什么在这个循环结束时字典值被覆盖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆