Home > Software design >  python iterate to append to a list, but all elements was changed to the last element
python iterate to append to a list, but all elements was changed to the last element

Time:06-21

        my_list = []
        pre_dict = {}

        for i in range(5):

            my_dict = {'Ali': 2, 'Luna': 6}

            if pre_dict:

                pre_dict['Ali'] = i
                print("[WTF] pre_dict: ", pre_dict)
                my_list.append(pre_dict)
                print("[WTF] my_list 1: ", my_list)

            else:
                
                my_dict['Ali'] = i
                print("[WTF] my_dict: ", my_dict)
                my_list.append(my_dict)
                print("[WTF] my_list 2: ", my_list)

                pre_dict = my_dict


        print("[WTF] my_list x: ", my_list)
        exit()

the output is :

[{'Ali': 4, 'Luna': 6}, {'Ali': 4, 'Luna': 6}, {'Ali': 4, 'Luna': 6}, {'Ali': 4, 'Luna': 6}, {'Ali': 4, 'Luna': 6}]

what I want is:

[{'Ali': 4, 'Luna': 6}, {'Ali': 3, 'Luna': 6}, {'Ali': 2, 'Luna': 6}, {'Ali': 1, 'Luna': 6}, {'Ali': 0, 'Luna': 6}]

I am very confused what is the logic. How to modify my code? anyone give some advice? thanks !

CodePudding user response:

You are facing a Python assignment problem. See: https://docs.python.org/3/library/copy.html

Assignment statements in Python do not copy objects, they create bindings between a target and an object.

Therefore, you should copy objects before append them to a list.

Example without copy.copy():

my_list = []
my_dict = {'A': None, 'B':6}

for i in range(5):
    my_dict['A'] = i
    my_list.append(my_dict)
    
print(my_list)
> [{'A': 4, 'B': 6}, {'A': 4, 'B': 6}, {'A': 4, 'B': 6}, {'A': 4, 'B': 6}, {'A': 4, 'B': 6}]

Example with copy.copy():

import copy

my_list = []
my_dict = {'A': None, 'B':6}

for i in range(5):
    my_dict['A'] = i
    my_list.append(copy.copy(my_dict))
    
print(my_list)
> [{'A': 0, 'B': 6}, {'A': 1, 'B': 6}, {'A': 2, 'B': 6}, {'A': 3, 'B': 6}, {'A': 4, 'B': 6}]

If you want a reverse order, use range(5-1, -1, -1).

CodePudding user response:

You can do it with a list comprehension:

[{'Ali':i, 'Luna':6} for i in reversed(range(5))]

Output:

[{'Ali': 4, 'Luna': 6},
 {'Ali': 3, 'Luna': 6},
 {'Ali': 2, 'Luna': 6},
 {'Ali': 1, 'Luna': 6},
 {'Ali': 0, 'Luna': 6}]

CodePudding user response:

You can use itemgetter from operator library to sort the list of dics, and I fixed your code to get the right values.

from operator import itemgetter

my_list = []
pre_dict = {}


for i in range(5):

    my_dict = {'Ali': 0, 'Luna': 6}

    if pre_dict:
        pre_dict['Ali'] = i 
        print("[WTF] pre_dict: ", pre_dict)
        my_list.append(pre_dict)
        print("[WTF] my_list 1: ", my_list)

    else:
        
        my_dict['Ali'] = i 
        print("[WTF] my_dict: ", my_dict)
        my_list.append(my_dict)
        print("[WTF] my_list 2: ", my_list)

Sortedlist = sorted(my_list, key=itemgetter('Ali'), reverse=True)

print("[WTF] my_list x: ", Sortedlist)
  • Related