2014-01-25 36 views
0

我有一個停靠公共交通站點的字典。我想複製那些正在傳輸的文件(有多個行),以便每個附加行都有一個停止複製停止。我最初將這些副本存儲在一個名爲duplicates的字典中。但是,在將相應行的名稱分配給每個複製停止位後,它們都會被原始停止位的原始行列表中的最後一行覆蓋。所以我最終得到了一堆重複的站點,所有站點都有相同的線路,而不是每個線路一站。什麼是壓倒這些價值?文件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']也重新分配停止[項目] [ 'duplicateStops']。這怎麼可能?重複和停止是兩個單獨的詞典。

回答

2

然後duplicates[duplicate_stop]stops[item]相同對象 - 和變異對象,那麼,改變對象。對象是而不是自動複製/克隆/複製在作業上或作爲函數參數使用時。

問題的行是最有可能

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

..和評論是錯誤因爲不發生重複。


問題Understanding dict.copy() - shallow or deep?可能會有用;至少它展示瞭如何製作一個真正的副本。