0

I have the following list "mylist" for which i created "foundkeys" function to search it for occurrence of another list "keys" items , The output will look like "formatted_list" now i pass the output of "foundkeys" to "reorder" function which reorders the content of passed "order" example of "foundkeys" into specific format .

The problem If i use the the above setup i don't get the exact output needed but if i pass '"formatted_list"' "which is the exact output of "foundkeys" ", to "reorder" instead of calling "foundkeys" , i would get the needed format

the correct output should be like this : with 'a' key having its elements starting with 'a' and 'k' key having its elements starting with 'k'

[['a', [[1, 'a', 'Asfoor', 'b', 'c'],
       [2, 'a', 'j', 'deek', 'k'],
       [3, 'a', 'k', 'bata', 'p']]],
 ['k', [[2, 'k', 'j', 'a', 'deek'],
       [3, 'k', 'bata', 'a', 'p'],
       [4, 'k', 'v', 'm', 'farkha']]]]

but if i use the setup i get the this wrong output: where it puts 'k' instead of 'a' in elements of of the 'a' key

[['a', [[1, 'a', 'Asfoor', 'b', 'c'],
       [2, 'k', 'j', 'deek', 'a'],
       [3, 'k', 'a', 'bata', 'p']]],
['k',  [[2, 'k', 'j', 'deek', 'a'],
       [3, 'k', 'a', 'bata', 'p'],
       [4, 'k', 'v', 'm', 'farkha']]]]

kindly have a look into the code for better understanding.

mylist=
    [[1, 'Asfoor', 'a', 'b', 'c'],
    [2, 'deek', 'j', 'a', 'k'],
    [3, 'bata', 'k', 'a', 'p'],
    [4,'farkha','v','m','k']]

keys = ['a', 'k']

def foundkeys(mylist,keys):
    def found(list, k):
        return k in list
    final = []
    for j in keys:
         final.append([j , [k for k in mylist if found(k, j)]])

    return final;
order=foundkeys(mylist,keys)
print("New list with found keys \n",order)    

formatted_list=
    [
        [
          'a', [[1, 'Asfoor', 'a', 'b', 'c'], [2, 'deek', 'j', 'a', 'k'], [3, 'bata', 'k', 'a', 'p']
        ]],
        [
          'k', [[2, 'deek', 'j', 'a', 'k'], [3, 'bata', 'k', 'a', 'p'], [4, 'farkha', 'v', 'm', 'k']]
        ]
    ]

def reorder(alist):

    for item in alist:
        key=item[0]
        value=item[1]
        for c,v_item in enumerate(value):
          old=value[c][1]
          for i,s_value in enumerate(value[c]):
              if s_value==key:
                 value[c][i]=old
                 value[c][1]=key

# calling reorder function with order function list
reorder(order)
print(order)
# calling reorder function with formatted_list instead
reorder(formatted_list)
print(formatted_list)

1 Answers1

1

Python use references to store the lists. To see this, try running the following code.

a = [1, 2]
b = [a for i in range(0, 3)]
print(b)    # prints out [[1, 2], [1, 2], [1, 2]]

b[0][0] = 4
print(b)    # prints out [[4, 2], [4, 2], [4, 2]]

[a for i in range(0, 3)] does not insert three "individual" a into b. It actually insert a's reference into b. So when we change an element through b[0][0], we change all the lists with the same reference.

To solve this, just ask python to create a new list, not just copying the reference.

a = [1, 2]
b = [list(a) for i in range(0, 3)]    # This line is different
print(b)    # prints out [[1, 2], [1, 2], [1, 2]]

b[0][0] = 4
print(b)    # prints out [[4, 2], [1, 2], [1, 2]]

So in your code, it should be

for j in keys:
    final.append([j , [list(k) for k in mylist if found(k, j)]])

And now you will get the same result using order and formatted_list.

You can see this post for more understanding about references and copies.

TsReaper
  • 845
  • 7
  • 19