-2

Edit: Resolved, I just was thinking wrong and the function never reached the second return for numbers bigger than n, so no need for anyone here to read it.

I know this is a "duplicate" - but not entirely. Currently I am using Python 3.6.2

I generate a list of primes and then want to copy it, so I can modify it to find a specific prime and also return the list of primes.

I tried:

new_list = old_list[:]
new_list = list(old_list)
new_list = old_list * 1
new_list = old_list.copy()
new_list = [char for char in old_list]

But NONE of those work. In my code I reduce the list of primes to just an integer, and then return the number and the list. But all modifications done to the old_list are done to the new_list, regardless of the method used.

Code in question:

def f(n):
    #generate primelist
    primes = []
    numbers = set(range(n,1,-1))
    while numbers:
            p = numbers.pop()
            primes.append(p)
            numbers.difference_update(set(range(p*2,n+1,p)))
    #any of these, none work
    primelist = primes[:]
    primelist = primes * 1
    primelist = primes.copy()
    primelist = list(primes)
    primelist = [char for char in primes]   
    #find even digits
    import re
    evendigs = re.compile(r'[24680]')
    longest = []
    prime = 0
    #remove n from primes if n is prime
    if n in primes:
        primes.remove(n)
    #find largest prime with maximum number of even digits that is smaller than n
    for i in list(reversed(primes)):
            if len(str(prime))> len(str(i)):
                return prime
            evenprime = re.findall(evendigs,str(i))
            if evenprime:
                    if len(evenprime)>len(longest):
                            longest = evenprime
                            prime = i
                    elif len(evenprime)==len(longest):
                            longest = evenprime
                            if i > prime:
                                prime = i
                    else: continue
    return (primelist, primes)

Also why does:

a,b = f(9451) raise the error: int object is not iterable?

assuming i only return e.g. primelist (which should be a list of primes up to n):

number = f(9451) but a = 8243 and a is not a list

returning primes (which should be a number, even though the number is wrong), gives the same value.

  • 1
    `primelist` is a copy, no doubt about that. Pity you then *ignore the copy*. – Martijn Pieters Sep 01 '17 at 07:49
  • Sorry I don't agree. I generate the list primes and copy that to primelist. Then I manipulate the list primes and return the primelist (and now after my edit also primes which is now a number). So obviously I ignore the primelist while manipulating the list primes, but I did return primelist (and now after my edit also primes), so I did not entirely ignore it. The problem is that both, primes and primelist, are returned as just an integer. – Benjamin Schwarz Sep 01 '17 at 08:39
  • Then show us what input you gave, what output you expected, and what you got instead. For any prime up to 23 that I tied, I get two different lists. – Martijn Pieters Sep 01 '17 at 08:44
  • In other words, the lists are definitely independent. You are creating a copy correctly. The copy is not the problem. – Martijn Pieters Sep 01 '17 at 08:46
  • It's also trivially testable: `result = f(....)` for any input, then `if isinstance(result, tuple): assert result[0] is not result[1], "returned the same list twice"`. Your returned objects are **not the same list object**. Because they contain immutable objects only, that **must** make them completely independent. – Martijn Pieters Sep 01 '17 at 08:48
  • Another way to test it: manipulate one of the returned lists. You'll not see the same change in the other list; ergo, they are independent, one started as a copy of the other. – Martijn Pieters Sep 01 '17 at 08:49
  • I added an edit with input, expected output and output. I never get any list as output. always just an integer. – Benjamin Schwarz Sep 01 '17 at 08:49
  • You'd need to reword your question drastically, as currently is is based on an entirely wrong assumption. – Martijn Pieters Sep 01 '17 at 08:50
  • Up to `f(23)` gives me a tuple of two lists. – Martijn Pieters Sep 01 '17 at 08:51
  • Oh man this just confuses me further, you are right, up until 23 it returns lists... I'll go back and see if I can make out the mistake... Thank you for pointing that out. – Benjamin Schwarz Sep 01 '17 at 08:52
  • Ah gotcha. It never even reached the second return... man sometimes I feel like I'm blind... – Benjamin Schwarz Sep 01 '17 at 08:58

3 Answers3

2

There is a problem in your code:

consider this example:

>> l = [1, 2, 3]
>> m = l
>> n = l[:]
>> l.append(4)
>> l
[1, 2, 3, 4]
>> m
[1, 2, 3, 4]
>> n
[1, 2, 3]

Most if not all of your examples should make a copy, albeit a shallow copy in most cases.

Back to your code:

 #remove n from primelist if n is prime
if n in primes:
    primes.remove(n)

This does not do what the comment suggests.

this should be

if n in primes:
    primelist.remove(n)
Daniel Lee
  • 7,189
  • 2
  • 26
  • 44
0

I also faced a similar problem. Try copying your existing list to another and then start manipulating the second list. It can be done by.

list2 = [x for x in list1] 

You can now make changes in list2 without affecting list1

Prabhu
  • 21
  • 4
-1

because the way you have tried all get newlist as a copy of oldlist,not a new list, you can try this:

newlist = []
for tmp in oldlist:
    newlist.append(tmp)
Hejun
  • 366
  • 2
  • 9
  • All of the other ways would have worked too. They know how to copy a list, they are just copying the wrong list in the wrong place. – Martijn Pieters Sep 01 '17 at 07:48