Reputation: 13
Im trying to count the number of elements in a nested list, the list looks like this:
[(1944, ['Hughes H']),
(1940, ['Hill DK', 'Crawford GN', 'Greene HS', 'Myers J', 'Burr GO']),
(1941,
['McClung CE',
'Sumner FB',
'Gates RR',
'Lewis WH',
'Haas O',
'Haas O',
'Gould BS',
'Tytell AA',
'Hatch MH']),
(1942,
['Gaffron H',
'Gardner FT',
'Edwards PR',
'Bruner DW',
'Lake NC',
'Ratner B',
'Gaffron H',
'Rubin J',
'Ritter WE']),
(1943,
['Bousfield G',
'Fishbein M',
'Faber HK',
'Silverberg RJ',
'Dong L',
'Howorth MB'])]
This is the code is used to get this output:
d = defaultdict(list)
for k, v in authors_expanded:
d[k].append(v)
d.items()
Using the following code works and just subtracting one works:
len(d.items())-1
Since the first element of the list always contains one item. I'm looking for a nicer solution tough.
Providing me a good link would be great too, i just can't seem to find any myself.
Upvotes: 1
Views: 6315
Reputation: 66
I appreciate the answer from @0C3D on this one, but it seemed incomplete to me when I tried it on a dict{dict: {[list]}} nested-collection:
{1727083382:
{1234: ['something', 'else'],
5678: ['yet', 'another']}}
Which bothered me because @0C3D said:
This will work no matter how many nested lists how have or how deep you need to go.
I added a type-check to the top level, because keys are not indecies, and this is working for me now.
You'll probably notice that I said f*** tuple
It would be pretty easy to add to the match
statement. Here we have a recursive function which will count nested dictionaries and lists, theoretically, regardless of depth:
# Recursively count list/dict
def count_items(items):
number = 0
top_type = str(type(items)).split("'")[1]
match top_type:
case 'dict':
for i in items.keys():
variable_type = type(items[i])
if variable_type is list or variable_type is tuple or variable_type is dict:
number = number + count_items(items[i])
else:
number = number + 1
case 'list':
for i in items:
variable_type = type(i)
if variable_type is list or variable_type is tuple or variable_type is dict:
number = number + count_items(items)
else:
number = number + 1
case no_match:
raise ValueError(f'{no_match} is not yet supported.')
return number
Upvotes: 0
Reputation: 2223
If you're looking for the number of authors per year, you could use this:
# Authors per year
authors_per_year = { year: len(authors) for year, authors in the_list }
Gives you this:
{1940: 5, 1941: 9, 1942: 9, 1943: 6, 1944: 1}
Or, if you looking for a count of unique authors then you could use this:
# Unique authors
unique_authors = set([ a for year, authors in the_list
for a in authors])
Gives you this set:
set(['Bousfield G',
'Bruner DW',
'Burr GO',
'Crawford GN',
'Dong L',
'Edwards PR',
'Faber HK',
'Fishbein M',
'Gaffron H',
'Gardner FT',
'Gates RR',
'Gould BS',
'Greene HS',
'Haas O',
'Hatch MH',
'Hill DK',
'Howorth MB',
'Hughes H',
'Lake NC',
'Lewis WH',
'McClung CE',
'Myers J',
'Ratner B',
'Ritter WE',
'Rubin J',
'Silverberg RJ',
'Sumner FB',
'Tytell AA'])
So len(unique_authors)
gives you a count of 28
.
In any case, I think the way forward for you may well be to use some combination of list comprehensions or dict comprehension.
Upvotes: 0
Reputation: 348
What you need is recursion. A function that calls itself. Test for the type when iterating through the list and if its another list recursively count the items within. Have a look below should do the trick. This will work no matter how many nested lists how have or how deep you need to go. You can also count nested tuples and dicts, although if you don't need to test for them I would remove them.
items = ['item1',['item2',['item3','item4']]]
def count_items(items):
number = 0
for i in items:
variable_type = type(i)
if variable_type is list or variable_type is tuple or variable_type is dict:
number = number + count_items(i)
else:
number = number + 1
return number
print count_items(items)
Upvotes: 0
Reputation: 19763
[ len(y) for x,y in your_list ]
output
[1, 5, 9, 9, 6]
I am taking x,y pair, y is the nested list. I am using len
function to give number of element in list
Upvotes: 0