com_thit_nuong
com_thit_nuong

Reputation: 29

Python | List Comprehension | Multiple Criteria

Use Case

I am trying to use multiple list comprehensions to create a list that includes elements and satisfies the following criteria.

Step 1: All elements are integers between 1 and 30 (inclusive). All elements are not divisible by 2 or by 5. Print out the list and move to the next step.

Step 2: Convert all elements that are divisible by 3 to their opposites (e.g. 3 to -3) and print out the new list (step-2 list).

Step 3: Sum up the value of all positive elements in the step-2 list and print out the result

My Code

Step 1: Create a list expression for all integers between 1 and 30 that are not divisible by 2 or 5. Print out the list

list1 = [a for a in range(1, 31) if a%2 == 1 & a%5 == 1]
print(f"My initial list is: {list1}")

Step 2: Convert all integers divisible by 3 to their opposites

list2 = [-abs(b), c for b in list1 if b%3 == 0 else ]
print(f"My step-2 list is: {list2}")

This is where I am stuck. How do I print all integers from list1 where any integers divisible by 3 become negative (e.g., 3 becomes -3) and all remaining integers not divisible by 3 as positive? This is the logic that I am trying to achieve.

If I use the following code below, it returns a list of [-3, -21] which is correct. However, I don't see the remaining positive integers not divisible by 3 in the list.

list2 = [-abs(b) for b in list1 if b%3 == 0]
print(f"My step-2 list is: {list2}")

Step 3: Sum all positive values in the second list and print out the result

list3 = [sum(c) for c in list2 if c > 0]
print(f"The sum of positive elements in my step-2 list is: {list3}")

I believe the code for list3 should work once I fix the code for list2. Any help is appreciated. Thank you.

Upvotes: 2

Views: 608

Answers (2)

Malo
Malo

Reputation: 1313

You could consider this fix and proposal for your goal: For step 3 list comprehension can keep the positive numbers, but another function like sum(..) is needed, otherwise maybee the reduce(..) function could also be used:

list1 = [a for a in range(1, 31) if a%2 != 0 and a%5 != 0]
print(f"My initial list is: {list1}")

list2 = [-abs(b) if b%3==0 else b for b in list1 ]
print(f"My step-2 list is: {list2}")

list3 = [x if x>0 else 0 for x in list2 ]
print(f"My step-3 list is: {list3} and sum is: {sum(list3)}")


My initial list is: [1, 3, 7, 9, 11, 13, 17, 19, 21, 23, 27, 29]
My step-2 list is: [1, -3, 7, -9, 11, 13, 17, 19, -21, 23, -27, 29]
My step-3 list is: [1, 0, 7, 0, 11, 13, 17, 19, 0, 23, 0, 29] and sum is: 120

For reference, you can do the final sum in one step only if you need:

list4 = [a  if a%2 != 0 and a%5 != 0 and a%3!=0 else 0 for a in range(1, 31)]
print(f"One step list is: {list4} and sum is: {sum(list4)}")

One step list is: [1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 11, 0, 13, 0, 0, 0, 17, 0, 19, 0, 0, 0, 23, 0, 0, 0, 0, 0, 29, 0] and sum is: 120

Upvotes: 1

Ondrej K.
Ondrej K.

Reputation: 9664

You need to place the conditional value in what the item in the list comprehension is, and not filter it, i.e.:

list2 = [-b if b % 3 == 0 else b for b in list1]

Go through each item in the list and if divisible by 3 return its negative value, otherwise return the number itself.

For the third step, you probably no longer want a list (and proposed construct would not be syntactically valid) and actually say:

result = sum(i for i in list2 if i > 0)

Relaying form the comments as noted by others: In the first step logical and operator is and and not & (which is a bit-wise operator). And for not divisible by n, just like in your second step, you should check the module is not 0 and not that it is 1.

Upvotes: 1

Related Questions