0

I have a simple python loop that iterate over a 2D list which has 1000 sublist inside. Each sublist will contain 3 string values. I only want to change the sublists which are after the 365th sublist. I also have a very trivial condition which will decide if an operation will be applied to the element. My minimum code is as follows:

def change_list(arr):
    for i in range(len(arr)):
        if i < 365:
            pass
        else:
            arr[i][1] = str(int(arr[i][1]) * 2)

When apply this function in main I'll simply invoke this function as: change_list(parsed_lines). For parsed lines, I'll just give a simple example:

parsed_lines = [["afkj","12","234"]] * 1000

My function will do the "multiply by 2" operation on all sublists, which is an unexpected behavior. I've tried not using conditions, but results in the same behavior.

for i in range(365, len(arr)):
    arr[i][1] = str(int(arr[i][1]) * 2)

Then I tried the other way to iterate my arr as:

for line in arr:
    if arr.index(line) < 365:
        print("I'm less than 365")
    else:
        line[1] = str(int(line[1]) * 2)

but this iteration will never execute the block under else. I am very confused by this, hope someone can help.

Update:

The expected behavior should be:

  1. For arr[0: 365], the sublist will stay the same as: [["afkj","12","234"]]
  2. For arr[365:], the sublist will be: [["afkj","24","234"]]
martineau
  • 119,623
  • 25
  • 170
  • 301
RandomEli
  • 1,527
  • 5
  • 30
  • 53
  • 1
    You are iterating over a *range*, which returns *integers* that you use to index into your *list*. Your list is only `len(arr) == 5`, so `i` is never not `i < 365`. – juanpa.arrivillaga May 01 '17 at 20:15
  • @juanpa.arrivillaga, I just gave portion of my data, the entire list has 1000 items. – RandomEli May 01 '17 at 20:18
  • you code is good just mixed up arr and parsed_lines I think – Serge May 01 '17 at 20:18
  • @LingboTang Well, then you need to provide a *reproducible example of the problem*. Furthermore, you need to be less vague about what you are expecting as output, and what you are actually trying to accomplish. – juanpa.arrivillaga May 01 '17 at 20:20
  • @juanpa.arrivillaga just multiply parsed_lines 100 times or so – Serge May 01 '17 at 20:22
  • @Serge And? What happens? More importantly, what is *expected to happen*? – juanpa.arrivillaga May 01 '17 at 20:23
  • he say for first snippet all elements are duplicated and none for second snippet. ( Just a sec ago he broke the list example i think to runtime error ) – Serge May 01 '17 at 20:26
  • @juanpa.arrivillaga I changed my description and has given the example you want. – RandomEli May 01 '17 at 20:28
  • @Serge I don't think so, I extracted this function out of my complicated `main`, and only gave the example in this question as parameter, I still got the unexpected result. – RandomEli May 01 '17 at 20:29
  • @LingboTang The example you provided *fails because of the way you are creating your example list*. `[[1,2,3]]*100` creates a list of lists of length 100 where each sublist *is the same list*. So changes will be reflected at every element. I don't think that is the root of your issue, though – juanpa.arrivillaga May 01 '17 at 20:32
  • In other words, if you are actually generating your list like `parsed_lines = [["afkj","12","234"]] * 1000` that, then *dont do that*. – juanpa.arrivillaga May 01 '17 at 20:32
  • @juanpa.arrivillaga That's what I'm thinking too because python hide some lower level reference to programmers. – RandomEli May 01 '17 at 20:37
  • was bad advice, direct multiply fails but map(list, [("afkj","12","234")] * 1000) should work – Serge May 01 '17 at 21:09
  • @Serge This is a neat solution. – RandomEli May 01 '17 at 22:14

1 Answers1

2

Your problem, as described, is not in the program, but in the test set. parsed_lines = [["afkj","12","234"]] * 1000 creates a list of 1000 references to the same list ["afkj","12","234"]. When it is modified through any of those references (say, above 365), it is seen as modified through any of those references (even below 365). In other words, parsed_lines[0][0]='foo' makes all fisrt elements in all sublists 'foo'.

DYZ
  • 55,249
  • 10
  • 64
  • 93