Reputation: 449
Using Python 2.7. I have the following list inside of a list:
channels = [[ch1a.twist, ch1b.twist, ch1c.twist, ch2a.bop, ch2b.bop, ch3c.pull]]
new_list = []
I want to apply the following logic to my code:
I would like to run the for loop such that
channels = [...]
new_list = []
for "blah":
do stuff
print new_list
>> new_list = [ch1a.twist, ch2a.bop, ch3c.pull]
So far I have
for list in channels:
for ch in list:
try:
prefix, suffix = ch.split('.')
except ValueError:
pass
else:
if 'a' in prefix:
new_list.append(ch)
elif 'b' in prefix:
new_list.append(ch)
but this is still returning the ch1a.twist and the ch1b.twist...grrrrrr. I thought 'elif' was supposed to mimic the following logic: 'else if previous condition was not met then execute the following'
Upvotes: 0
Views: 54
Reputation: 1116
I got the same error as @roganjosh, so I've assumed that your list-within-a-list should contain strings (it's a simple enough change if they're not).
The main issue with your provided code is that if you ever hit the code to check whether 'b' is in the prefix, then you are never looking to see whether you've already added the channel number to new_list
.
The easiest way I've found to modify your code is as follows (it's not pretty, but I was trying to keep your code as un-touched as possible):
Firstly, sort the list-within-a-list using channels[0].sort()
Next, track which channel number you have already added by initialising a list using channelNumbers = []
Next, I split the prefix so that I separate the channel number from the channel version:
channelNumber = prefix[:-1]
channelVersion = prefix[-1:]
Finally, I tweak your elif
statements so that they only add the b- or c- versions if the channel number hasn't already been added:
elif 'b' in prefix and not channelNumber in channelNumbers:
and elif 'c' in prefix and not channelNumber in channelNumbers:
So the full code becomes:
channels = [['ch1a.twist', 'ch1b.twist', 'ch1c.twist', 'ch2a.bop', 'ch2b.bop', 'ch3c.pull']]
new_list = []
channelNumbers = []
channels[0].sort()
for list in channels:
for ch in list:
try:
prefix, suffix = ch.split('.')
channelNumber = prefix[:-1]
channelVersion = prefix[-1:]
except ValueError:
pass
else:
if channelVersion == 'a':
new_list.append(ch)
channelNumbers.append(channelNumber)
elif channelVersion == 'b' and not channelNumber in channelNumbers:
new_list.append(ch)
elif channelVersion == 'c' and not channelNumber in channelNumbers:
new_list.append(ch)
print(new_list)
And the output is, as you requested: ['ch1a.twist', 'ch2a.bop', 'ch3c.pull']
Upvotes: 0
Reputation: 76194
Assuming:
ch1a.twist
et al to be string literals, and just forgot the quote markschannels
contains exactly one listThen you can use groupby
to group the items by channel name, and extract the first occurrence of each channel using next
.
import itertools
def channel_name(channel):
prefix, suffix = channel.split(".")
return prefix[:-1]
channels = [["ch1a.twist", "ch1b.twist", "ch1c.twist", "ch2a.bop", "ch2b.bop", "ch3c.pull"]]
result = [next(v) for k,v in itertools.groupby(channels[0], key=channel_name)]
print(result)
Result:
['ch1a.twist', 'ch2a.bop', 'ch3c.pull']
Upvotes: 1