0

I just don't get it. Please see my code below...

def startscan(rangeip,ports,cblocks):
    pool = ThreadPool(processes=MAX_THREADS)
    results = []
    testt = []
    #print(rangeip)
    #print(ports)
    #print(cblocks)
    for ii in range(cblocks):
     print(rangeip[2])
     rangeip[2] = int(rangeip[2]) + 1
     print(rangeip[2])
     print(rangeip)
     testt.append(rangeip)
    print(testt)

When I run it it returns this output :

root@node2nl home]# python g.py -r 192.168.20.1 -p 80 -a 3
20
21
['192', '168', 21, '1']
21
22
['192', '168', 22, '1']
22
23
['192', '168', 23, '1']

[['192', '168', 23, '1'], ['192', '168', 23, '1'], ['192', '168', 23, '1']]

As you can see all is correct except the list testt does not gett filled right. It shows three times the same value. I need it to output the right result like below

[['192', '168', 21, '1'], ['192', '168', 22, '1'], ['192', '168', 23, '1']]

What am I doing wrong ? It seems like something very weird is going on here.

r-d-r-b-3
  • 325
  • 2
  • 11
  • You are appending the same object `rangeip` to your `ttest` list, so what ever you have in your `ttest` are purely duplicates of `rangeip` which will store the current value referenced by this object – Iron Fist Dec 22 '16 at 05:11
  • Briefly: `testt.append(rangeip[:])`. – TigerhawkT3 Dec 22 '16 at 05:13
  • Ok I get your answer but then why does it work with print and with append not. That is the weird thing i can not understand. – r-d-r-b-3 Dec 22 '16 at 05:17
  • `rangeip[2] = int(rangeip[2]) + 1` doesnt work for me `TypeError: 'str' object does not support item assignment`. Is `rangeip`a string or a list? Your question should (or should have) included how `startscan` is called!! – Paul Rooney Dec 22 '16 at 05:19

2 Answers2

0

The rangerip list is appended by it's reference, not the copy of the list. Therefore the result contains three times the same reference at the end.

You need to copy/clone the list, there are several ways:

import copy
...
     testt.append(copy.copy(rangeip))
     #  or shorter rangerip[:]

Note that additionally the original parameter rangeip is modified, which is not good practice. You may consider doing the copying before incrementing and rather adding ii+1 instead of 1.

Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
  • Yes got it but why does print(rangeip) in my example gives me the correct result : print(rangeip) ==> ['192', '168', 21, '1'] and with append giving an other result. Why is that ? – r-d-r-b-3 Dec 22 '16 at 05:25
  • @skanilos : because it prints current state. But the current content changes with every increment. – Zbynek Vyskovsky - kvr000 Dec 22 '16 at 05:27
  • Ok but why does testt.append(rangeip) not add rangeip in its current modfied state ? Just as print prints the right rangeip in it currents state as you mentioned. That is the whole unclear part for me.. – r-d-r-b-3 Dec 22 '16 at 05:28
  • @skanilos : it does. But later the content is modified by next loop as it's still the same instance of the array. – Zbynek Vyskovsky - kvr000 Dec 22 '16 at 05:31
  • Sorry that last part I dont understand clearly. " later the content is modified by next loop as it's still the same instance of the array" – r-d-r-b-3 Dec 22 '16 at 05:32
  • I was thinking a fixed part "value" got stored.. ? if i understand you right it stores variable ? – r-d-r-b-3 Dec 22 '16 at 05:35
  • Your list has 3 entries and they all point to the same list. So when you print it shows 3 of the same thing, which is basically the state you left it in after the final iteration. – Paul Rooney Dec 22 '16 at 06:11
0

You need to make a copy of rangeip when you add it to the list. Your code currently just adds a reference to the list to the ttest list three times, but keeps changing rangeip. Replace ttest.append(rangeip) with ttest.append(rangeip[:]) to get the result you want.

cco
  • 5,873
  • 1
  • 16
  • 21
  • Ok, that worked ! But why in my original code does with print(rangeip) it returns the correct rangeip ? print(rangeip) ==> ['192', '168', 21, '1'] – r-d-r-b-3 Dec 22 '16 at 05:19