1

I have code that looks like:

Loop that appends player names to a list called playerlist
print(playerlist)
lineuplist.append(playerlist)

The print statement ends up printing a list that looks like:

...
['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Pau Gasol', 'Paul Millsap', 'Chandler Parsons', 'Kevin Durant']
['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Serge Ibaka', 'Pau Gasol', 'Kevin Durant', 'Chandler Parsons']
['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Serge Ibaka', 'Pau Gasol', 'Chandler Parsons', 'Kevin Durant']
['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Paul Millsap', 'Pau Gasol', 'Kevin Durant', 'Chandler Parsons']
...

I want my output to be a list of those lists, ie:

[['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Pau Gasol', 'Paul Millsap', 'Chandler Parsons', 'Kevin Durant'],     ['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Serge Ibaka', 'Pau Gasol', 'Kevin Durant', 'Chandler Parsons'], ['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Serge Ibaka', 'Pau Gasol', 'Chandler Parsons', 'Kevin Durant'],     ['Omer Asik', 'Jordan Farmar', 'Patrick Beverley', 'Kyle Korver', 'Kent Bazemore', 'Paul Millsap', 'Pau Gasol', 'Kevin Durant', 'Chandler Parsons']]

However, all I get is this:

print(lineuplist)
[[], [], [], [], []]

Not really sure where I'm going wrong, so any help is appreciated.

Russia Must Remove Putin
  • 337,988
  • 84
  • 391
  • 326

2 Answers2

3

When you append the list into your main list, you're actually appending a pointer to that original list. Python lists are mutable, and when you change them, you change them wherever you have a pointer to them.

If you append a copy of them, you can avoid this being an issue, but you'll waste memory, so it's important to have a good reason to copy them.

Here's an example of this behavior:

>>> l = list('abc')
>>> m = [l.copy()]
>>> m
[['a', 'b', 'c']]
>>> l.remove('a')
>>> m
[['a', 'b', 'c']]
>>> l
['b', 'c']

So what you could do is this:

lineuplist.append(playerlist.copy())

instead of this:

lineuplist.append(playerlist)
Russia Must Remove Putin
  • 337,988
  • 84
  • 391
  • 326
  • There should be an addendum to this about scope. If for example you have defined `lineups` outside of the loop scope, and `playerlist` **inside it** and do not manipulate `playerlist` inside the scope of the loop beyond assigning it to some value before you do the append, then it will do what you expect because `playerlist` is a new list every iteration of the list. If, however, `playerlist` is defined **outside** the scope of the the loop, then you will get the behavior described by the OP because every iteration of the loop is operating on the same `playerlist` – aruisdante Mar 14 '14 at 12:56
1

The actual problem with the content of the lists disappearing has already been solved in the other answer, however I want to note that you can make your code a whole lot simpler.

If I understand the code (now removed from the question) correctly, you are looking for combinations of players forming a legal lineup for a team whose combined salary is within certain bounds. The team needs one player from the C group (captain?), and 2 from each of the PG, SG, PF, and SF groups.

You can use the itertools module for this, particularly product and combinations.

from itertools import product, combinations
player_combinations = product(combinations(C, 1), 
                              combinations(PG, 2),
                              combinations(SG, 2),
                              combinations(PF, 2),
                              combinations(SF, 2))

(Update: This returns nested lists of tuples, so you need to flatten it first. You can use sum for this.)

player_combinations = (sum(pc, ()) for pc in player_combinations)

The result is an iterator with all the combinations of players (the entire objects, not just the names). Now you can find the teams that satisfy the salary criterion in just a single loop and extract their names:

lineuplist = []
for players in player_combinations:
    salary = sum(player[5] for player in players)
    if salarycap - undersalary <= salary <= salarycap:
        names = [player[1] for player in players]
        lineuplist.append(names)
tobias_k
  • 78,071
  • 11
  • 109
  • 168
  • I was just about to post a link to [permutations](http://docs.python.org/2/library/itertools.html#itertools.permutations) for getting all subsets of a given size from some larger list. – aruisdante Mar 14 '14 at 13:05
  • salary = sum(player[5] for player in players) IndexError: tuple index out of range I'm getting that as an error when I try to run that last block of code. –  Mar 18 '14 at 12:48
  • 1
    Well, you used e.g. `salary += int(n4[5])` to get the salary. Did the format of the player lines change since then? – tobias_k Mar 18 '14 at 13:00
  • I actually just changed it so its in index 2. But I adjusted the code to account for that. –  Mar 18 '14 at 13:01
  • @Tobias_k I noticed when I tried `for player in players: print(str(player) + "\n")` it prints out `(['SF', 'Mike Dunleavy', '5000'], ['SF', 'Evan Turner', '4600']) (['C', 'Al Jefferson', '9700'],) (['PG', 'Chris Paul', '9400'], ['PG', 'Russell Westbrook', '8900']) (['SG', 'Eric Bledsoe', '7300'], ['SG', 'Vince Carter', '5400'])` which seems like there's two entries in one line? –  Mar 18 '14 at 13:02
  • I also get this too: ` salary = sum(player[2] for player in players) TypeError: unsupported operand type(s) for +: 'int' and 'str'` –  Mar 18 '14 at 13:06
  • 1
    @Wilson Did you use the `sum` line between the two code blocks to flatten the tuples? About the type error: If salary is a string, you have to convert it to int first, e.g. `sum(int(player[5]) for player in players)` – tobias_k Mar 18 '14 at 13:11
  • @tobias_k it does seem to be a problem that it calculates the salaries based on the tuple of the 2 positions, ie it does c, then pg, then sg, as I showed above when I printed player. –  Mar 18 '14 at 13:22
  • Actually updated my other question so it's easier for you to see. I changed the code now and it works. [link](http://stackoverflow.com/questions/22479267/large-loop-nest-design-anyway-to-improve-speed/22480903#22480903) –  Mar 18 '14 at 13:30