0

I have created a function and am passing the function a list of strings like this: ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'XX']

I have created a variable X with 26 values; I refer to these values as 'card' in my code below ('for card in X').

I am using itertools and list comprehensions to create a list of strings so that each value in X is substituted for 'XX' in a new list.

For example: ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'XX'] will expand to ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value1'], ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value2'] etc

I am creating a list of values called tmp and substituting the list of 'X' values (called card) for one of the items in tmp (called 'XX') using a for loop.

 unitoffive = list(itertools.combinations(unit,5))
 newunit = [list(line) for line in unitoffive if 'XX' in line]


 tmp = [[line,card] for line in newunit for card in X]
 for line in tmp:
     line[0][4] = line.pop(line.index(line[1]))
     print line

  for line in tmp:
     print line

My script is exhibiting behavior I cannot understand. When the print line statement in my first for loop is executed I see the modified list that I expect. When the second print line statement is called I see another and incorrect version of my list. I can't return and use tmp since it only seems to contain the correct values within the for loop in which it was modified.

I know that Python lists can be tricky to modify in a for loop and I tried changing my code to loop over for line in tmp[:] but that didn't solve my problem.

The print line statement in this section of code prints ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value1'], ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value2'] etc as expected:

for line in tmp:
  line[0][4] = line.pop(line.index(line[1]))
  print line

The print line statement following it prints ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value26'], ['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value26'] etc

5
  • 1
    What input are you giving the script? What output are you getting? What output were you expecting? Can you please include that in your question? Commented Apr 21, 2012 at 21:13
  • The only thing you cant do while looping over a list is changing it's length. Add some sample data and it should be easy to find your bug. Commented Apr 21, 2012 at 21:19
  • This code does what I would expect, after reading it and testing it with some random strings. I think you're going to have to explain what you're putting in, and what you want to get. Commented Apr 21, 2012 at 21:28
  • 1
    Also, I must admit I'm pretty mystified about why you're doing line.pop(line.index(line[1])) when it does the same thing as line.pop(1), or line.pop(0) if line[0] and line[1] are identical. Commented Apr 21, 2012 at 21:30
  • 1
    @JoelCornett I will edit my post with input and output. @ senderle line.pop(1) will do what I need. My code has gotten sloppy as my frustration grows. Commented Apr 21, 2012 at 22:01

1 Answer 1

1

You're changing the [line, card] sublists and expecting the tmp list to have a copy of them, not the same objects. Try changing:

for line in tmp:

For:

import copy
for line in copy.deepcopy(tmp):

And see if it works as you expect.

edit

It seems like this is what you want, to append to the inlist instead of inserting:

>>> line = [['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'XX'], ['value1']]
>>> line[0].append(line.pop()[0])
>>> line
[['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'XX', 'value1']]
>>> 
Sign up to request clarification or add additional context in comments.

5 Comments

replacing line in tmp for line in copy.deepcopy(tmp) changes my results but not in the way that I need. You've convinced me that I really don't understand some aspects of python lists. If I am changing the [line,card] lists which are being created in tmp via list comp, then why wouldn't tmp have a copy of them?
tmp has a copy of the sublists, but not of the items inside them.
are you sure line.pop(1) is what you want to do? pop removes that item from the list and you're not inserting it again, but assiging it to someone else. You're effectly shortening your list while iterating over it, and that's why the print after it gives a different result.
yes, I do want to pop off line[1] and replace line[0][4] with the value in line[1]. I am open to changing my code if what I want is not going to work but I am struggling to understand why it doesn't work right now.
here's an example of what I am trying to do. I have a list like this: [['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'XX'],[value1]] I want to pop off value one and replace 'XX' with value1 so that my list looks like this: [['CC', 'DC', 'EC', 'FC', 'GC', 'HC', 'value1']]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.