Linda
Linda

Reputation: 307

how to create a sub list for a specific string in a nested list

I have Python nested list that I'm trying to organize and eventually count number of occurrences. The nested list looks like:

[['22', '1'], ['21', '15'], ['11', '3'], ['31', '4'], ['41', '13'],...]

The first I want to do is create a sublist that only contains '1' corresponding to the second item in the nested list. I was able to do this by the following command:

Subbasin_1 = []
Subbasin_1.append([x for x in Subbasins_Imp if x[1] == '1'])
print Subbasin_1

Giving these results, which are correct:

[['21', '1'], ['21', '1'], ['21', '1'], ['21', '1'], ['22', '1'],...]

Now I want to create another sublist that will give me all the '21' in the each nested list for Subbasin_1. When I use the same line of script, but change the appropriate items, I get an empty list. Not sure what is going on...?

OS_Count1 = []
OS_Count1.append([x for x in Subbasin_1 if x[0] == '21'])
print OS_Count1

Result is [[]] ??? What's the difference between the two? Thanks for any help...

Upvotes: 1

Views: 416

Answers (4)

JMDeschenes
JMDeschenes

Reputation: 31

Running your code I obtained a triple nested list....

Sub = [[['21','1'],....]]

Instead of doing:

  Subbasin_1 = []
  Subbasin_1.append([x for x in Sub if x[1]=='1'])

Simple do the list comprehension :

Subbasin_1 = [x for x in Sub if x[1] == '1']

This will give you the result you are expecting.

Upvotes: 2

Marius
Marius

Reputation: 60160

Your list comprehension [x for x in Subbasins_Imp if x[1] == '1'] creates a list by itself, which means when you append that list to Subbasin_1, you end up with a doubly nested list.

Compare:

sub_imp = [['22', '1'], ['21', '15'], ['11', '3'], ['31', '4'], ['41', '13']]
sub_1 = [x for x in sub_imp if x[1] == '1']
sub_2 = []
sub_2.append([x for x in sub_imp if x[1] == '1'])

print(sub_1)
print(sub_2)

Upvotes: 2

DSM
DSM

Reputation: 353379

I don't believe that your

[['21', '1'], ['21', '1'], ['21', '1'], ['21', '1'], ['22', '1'],...]

line could be produced by the code you gave. Your Subbasin_1.append line appends a list to the empty list Subbasin_1, so you should get something like

[[['22', '1'], ['21', '1']]]

with one extra level of nesting.

If you avoid the unnecessary construction of an empty list + append, you should get what you want:

>>> Subbasins_Imp = [['22', '1'], ['21', '15'], ['11', '3'], ['31', '4'], ['41', '13'], ['21', '1']]
>>> 
>>> Subbasin_1 = [x for x in Subbasins_Imp if x[1] == '1']
>>> print Subbasin_1
[['22', '1'], ['21', '1']]
>>> OS_Count1 = [x for x in Subbasin_1 if x[0] == '21']
>>> print OS_Count1
[['21', '1']]

Alternatively, you could simply replace append by extend. I don't recommend this, but it might help you to see what's happening:

>>> Subbasins_Imp = [['22', '1'], ['21', '15'], ['11', '3'], ['31', '4'], ['41', '13'], ['21', '1']]
>>> 
>>> Subbasin_1 = []
>>> Subbasin_1.extend([x for x in Subbasins_Imp if x[1] == '1'])
>>> print Subbasin_1
[['22', '1'], ['21', '1']]
>>> 
>>> OS_Count1 = []
>>> OS_Count1.extend([x for x in Subbasin_1 if x[0] == '21'])
>>> print OS_Count1
[['21', '1']]

Upvotes: 3

SpliFF
SpliFF

Reputation: 39004

There is no difference which implies Subbasin_1 might be empty at the time of the call or doesn't contain the data you think it does. It might also be that Subbasin_1 is nested 3 layers deep, not 2.

Upvotes: 0

Related Questions