1

I have a function that I'd like to iterate over a list of lists. The thing is, this list of lists is dynamic, meaning it changes based on user input.

Here is an example of my code:

result = func(5)
for z in Z[0]:
    result += func(z)

where Z is the dynamic lists of lists and func is my function. The function should iterate over every element in the list subsetted list Z[0] and sum the results. The code works when the list of lists looks like this:

Z = [[1.1],[2.1],[3.1],[4.1]]

were Z[0] is just [1.1]. However sometimes this dynamic list of lists has more elements in each list, in which case i need to iterate over each element. Like below:

Z = [list([1.1, 1.3]),list([3.1]),list([4]])

in which case:

Z[0] = [list([1.1, 1.3])]

and my code should do the following:

result = func(5)
for z in Z[0]:
    result += func(z)

....
func(1.1) + func(1.3)

When I try to run the code with the list of lists I get an error: "can only concatenate list (not "float") to list"

I'm sure it has something to do with trying to iterate over a list. If anyone has an easy fix to this, or knows the issue i'd love to know.

EDIT: I suppose my real issue is how these dynamic lists are being formed as pointed out by the answers below, I'll try to explain my issue a little further:

I'm using an answer here given by @Michael: Replacing certain elements of an array based on a given index

here is the code i use to produce the list of lists:

Arr1 = [9,7,3,1]

Arr2 = [[14,6],[13,2]]

Arr3 = [0,2]

Z = np.array([[Arr1[i]] if not np.sum(Arr3 == i) else Arr2[i] for i in np.arange(Arr1.size)], dtype=object)

Z = [[list([14, 6])], [list([7])], list[([13, 2])], list[([1])]]

Subsetting Z[0] results with

[list([14,6])]

which then gives me the error (can only concatenate list (not "float") to list) when i try to iterate .

When the condition i = Arr3 is not met (say Arr3 was empty) and it just reverts to the original array the output of this code gives:

Z = [[9][7][3][1]]

Z[0] = [9]

And with that the code to iterate over the list works. However I need to work for above as well.

IF I remove brackets from this line of code here:

Z = np.array([[Arr1[i]] if not np.sum(Arr3 == i) else Arr2[i] for i in np.arange(Arr1.size)], dtype=object) 

remove brackets around [Arr1[i]]
--->

Z = np.array([Arr1[i] if not np.sum(Arr3 == i) else Arr2[i] for i in np.arange(Arr1.size)], dtype=object)

Then

Z = [list([14,6]),list([7]),list([13,2]),list([1])]

and
z[0] = [14,6]

and the code to iterate over the list works! But, then it does not work for the situation when the condition i = Arr 3 is not met, because the output looks like

[9 7 3 1]

Z[0] = 9

and I get the error 'float' object is not iterable.

Sorry that is a lot, but I think it explains my issue better. I'm unsure out to get the list formation correct for any situation.

Melanie
  • 109
  • 1
  • 9
  • Are you just wanting to [flatten](https://stackoverflow.com/questions/952914/how-to-make-a-flat-list-out-of-a-list-of-lists) the list, then? – Random Davis Nov 30 '21 at 22:35
  • I'm wondering about your second list. Is that really what it looks like? Because that's a list of lists of lists. Is it really `[[1.1, 1.3], [3.1], [4]]`, or is there another nesting level in there, like `[[[1.1,1.3]], [[3.1]], [[4]]]`? – Tim Roberts Nov 30 '21 at 22:37
  • @TimRoberts yes there is a third nesting level with the word list. it looks like this: [[list([elements])]]. I'm trying to figure out how to get rid of this third nest now. – Melanie Dec 01 '21 at 12:51

5 Answers5

0

its hard to kind of make sense of your question, but if you are just trying to sum each list of nums inside the main list then you can do something like

def sum_nums(nums: list):
    return [sum(num) for num in nums]


nums = [
    [1, 2],
    [7, 9, 10],
    [2],
    [9]
]

print(sum_nums(nums))

OUTPUT

[3, 26, 2, 9]
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
0

If every element of Z is a list, just with differing sizes (i.e. [1.1], or [1.1, 2.2], etc.) You can iterate over the list and the size of the list will not matter.

for l in Z:
    result = 0

    for z in l:
        result += func(z)

    # do something with inner list result

For each list in Z, [1.1] is a list, and then for each element in the lists in Z, if above then 1.1, run func on this value and then add to result.

If Z can be a list of elements that are not a list, (i.e. Z = [1.1, 2.2]) then this method will not work, but you have not shown this to be your case.

EDIT - added in result to list to get sums of inner lists individually

fam-woodpecker
  • 500
  • 2
  • 10
0

Your input is:

Z = [[1.1, 1.3],[2.1],[3.1],[4.1]]

I think what you need to do is iterate over all elements, apply your function and add the results and return

def sum_of_all_elements(list_of_list):
   result = 0
   for nested_list in list_of_list:
      for element in nested_list:
         result += func(element)
   return result
print(sum_of_all_elements(Z))

Using line comprehension

result = sum([ func(element) for element in nested_list for nested_list in Z])
Aditya Landge
  • 1,177
  • 1
  • 10
  • 18
0

Your logic looks correct. I tested it on both examples you provided with the code below, and it produces the correct results.

def func(x):
    return x**2

Z1 = [[1.1],[2.1],[3.1],[4.1]] # works
Z2 = [list([1.1, 1.3]), list([3.1]), list([4])] # works
 
result1 = func(5)
for z in Z1[0]:
    result1 += func(z)
print(result1)
## Result is 26.21
# (5**2) + (1.1**2) = 25 + 1.21 = 26.21

result2 = func(5)
for z in Z2[0]:
    result2 += func(z)
print(result2)
## Result is 26.21
# (5**2) + (1.1**2) + (1.3**2) = 25 + 1.21 + 1.69 = 27.9

However, I believe your issue arises when the input array Z has more layers of nested lists than is expected. In the example below, the value "1" is formatted as a separate list. When the code iterates over 1.1 and 1.3, it can handle both of these cases because they are floats. Once the code gets to the third element which is formatted as a list [1], it is "surprised" and does not know how to handle the list because it was expecting a float. The code was not designed to expect this new extra list layer.

Z3 = [list([1.1, 1.3, [1]]), list([3.1]), list([4])] # does not work

result3 = func(5)
for z in Z3[0]:
    result3 += func(z) ## Error occurs on this line
print(result3)

To avoid this issue, you could make sure the user does not input more nested lists than is expected by your code. Alternatively, instead of using nested lists, you could use numpy arrays or pandas dataframes and add a new dimension instead of a new level of a nested list.

  • I think you're right. My issue is the list formation. I edited to explain how the list formation works. – Melanie Dec 01 '21 at 13:22
0
numbers = [1, 2, 3, 4, 5, 6]
new_number = [n + 1 for n in range (1, 10)]
name = "AKHIL  CHOWDARY"
new_name = [letter for letter in name if letter! = " "]
print(new_number, new_name)
new_number = [n + n for n in range(15) if n % 2   != 0]
print(new_number)
names = ["akhil", "mahesh", "suresh", "rajesh", "dinesh"]
new_names = [name for name in names if len(name) > 5]
print(new_names)
  • this for the lists with if condition – Akhil Chowdary Dec 02 '21 at 11:48
  • Hi @akhil-chowdary and welcome to Stack Overflow. When answering a question, try to provide an explanation of what you have done and why. Also, it's better to edit your question than clarify things in the comments. – Mike Dec 02 '21 at 13:11