How to overwrite a nested list using conditional list comprehension - python-3.x

I'm trying to check a nested for the bigger number in each and overwrite each nested list with just the value of the number with the biggest value.
I have done this using nested loops but I was wondering how to do this using conditional list comprehension.
Here's my nested loop solution:
list1 = [[1,2,4,3], [1,2,755,244], [1,2,6,1000] , [5,3,7,13]]
iterator = 0
for val1 in list1:
for num in val1:
if num == max(val1):
list1[iterator] = num
iterator +=1
Here's what I tried with list comprehension but the syntax is wrong:
num for x in list1 for num in x if num ==max(x)
The error is: invalid syntax

The coded you pasted works just fine. That being said you can write it much cleaner:
list1 = [[1,2,4,3], [1,2,755,244], [1,2,6,1000] , [5,3,7,13]]
iterator = 0
for index, val in enumerate(list1):
list1[index] = max(val)
print(list1) # [4, 755, 1000, 13]
The cleaner yet, listcomp version with max:
list1 = [[1,2,4,3], [1,2,755,244], [1,2,6,1000] , [5,3,7,13]]
list1 = [max(lst) for lst in list1]
print(list1) # [4, 755, 1000, 13]

Related

Modulo 10^9 +7 python

I have a list let's say : [1,3,5,6....,n] to very large number, that I need to report each number in the list in a new list but in "modulo 10^9+7" format in python.
How do I do it please?
I tried to search for it and people answer it's (n%m=p) and the solution is p, but I guess that's not it.
Some ways to do it. The first method is called list comprehension, and you can find many examples of it on stack overflow and elsewhere.
list1 = [1, 3, 5, 6, 201, 99121, 191929912, 8129391828989123]
modulus = 10**9 + 7
list2 = [x % modulus for x in list1] # example of list comprehension
or using map
list2 = list(map(lambda x: x % modulus, list1))
or perhaps the least elegant
list2 = []
for x in list1:
list2.append(x % modulus)

Why does this list return [False, False, 3, True]?

I've been working through an exercise on Kaggle and was tasked with: Return a list with the same length as L, where the value at index i is True if L[i] is greater than thresh, and False otherwise.
L = [1, 2, 3, 4]
LL = L
for nums in L:
if L[nums] > 2:
LL[nums] = True
else:
LL[nums] = False
print(LL)
That is what I came up with but it prints the list [False, False, 3, True]. Also, I replaced the variable "thresh" with the number 2 and added a print instead of a return statement since it's not a function. I'm guessing that this result is because when it hits the 3 or the number in index #2 in the list it for some reason skips over it and I cannot seem to figure out why?
Problem:
Your for loop is wrong. You are using nums as if it were an index in the array; the problem is that the in keyword in Python gives you the actual items from the list, which in this case are the numbers themselves. For example:
my_list = [5,3,1,6]
for num in my_list:
print(num)
# prints 5,3,1,6
Also, you should create a deep copy of the original list so that you don't overwrite the original list:
LL = L.copy()
Hint: if based on this, you understand what's wrong, try to implement it correctly before reading the solution below!
Solution:
The correct way to implement this:
L = [1, 2, 3, 4]
LL = L.copy() # this creates an actual copy, not just a reference
for i in range(len(L)):
if L[i] > 2:
LL[i] = True
else:
LL[i] = False
print(LL)

In the for loop why does it not square the last number in the list?

I am trying to create a code that will add up a list of numbers which have been squared. I am pretty new to python, so I was wondering if someone could explain why the list1 produced does not include the last number squared. The list2 always seems to start with 0. Can someone explain why?
import math
list2=[]
values=input("Please enter your vector coordinates")
list1=values.split()
print(list1)
for i in range(len(list1)):
value=i**2
list2.append(value)
print(list2)
i is the index, not the value, you can use either indexing:
for i in range(len(list1)):
value = list1[i]**2
list2.append(value)
Or simply use for i in list1:
for i in list1:
value = i**2
list2.append(value)
Even simpler with a list comprehension:
list2 = [i ** 2 for i in list1]
list2 always starts with a 0 because the first value of i is always 0. When you call range(len(list1)), you are asking for all the numbers in the sequence 0, 1, 2, 3, ..., N; where N is the number of elements in list1. Note that these are not the specific elements in list1.
Assuming that list1 has numbers in it, creating list2 with the squares of the corresponding numbers can be achieved in this way:
list2 = []
for num in list1:
v = num**2
list2.append(v)
There's another error in your code: list1 does not contain numbers as desired. In fact, it contains a bunch of strings (each of which looks like a number) but these are strs, not ints. This is because input returns a string, not ints. Continuing from there, values.split() gives you a list of strings, not a list of numbers. So you'll have to cast them to ints yourself:
list1 = [int(v) for v in values.split()]
Here's how I'd write this code:
list2 = []
values = input("Please enter your vector coordinates")
list1 = list(map(int, values.split()))
print(list1)
for num in list1:
list2.append(num**2)
print(list2)

How to delete certain element(s) from an array?

I have a 2d array, how can I delete certain element(s) from it?
x = [[2,3,4,5,2],[5,3,6,7,9,2],[34,5,7],[2,46,7,4,36]]
for i in range(len(x)):
for j in range(len(x[i])):
if x[i][j] == 2:
del x[i][j]
This will destroy the array and returns error "list index out of range".
you can use pop on the list item. For example -
>>> array = [[1,2,3,4], [6,7,8,9]]
>>> array [1].pop(3)
>>> array
[[1, 2, 3, 4], [6, 7, 8]]
I think this can solve your problem.
x = [[2,3,4,5,2],[5,3,6,7,9,2],[34,5,7],[2,46,7,4,36]]
for i in range(len(x)):
for j in range(len(x[i])):
if j<len(x[i]):
if x[i][j] == 2:
del x[i][j]
I have tested it locally and working as expected.Hope it will help.
Mutating a list while iterating over it is always a bad idea. Just make a new list and add everything except those items you want to exclude. Such as:
x = [[2,3,4,5,2],[5,3,6,7,9,2],[34,5,7],[2,46,7,4,36]]
new_array = []
temp = []
delete_val = 2
for list_ in x:
for element in list_:
if element != delete_val:
temp.append(element)
new_array.append(temp)
temp = []
x = new_array
print(x)
Edit: made it a little more pythonic by omitting list indices.
I think this is more readable at the cost of temporarily more memory usage (making a new list) compared to the solution that Sai prateek has offered.

If I have duplicates in a list with brackets, what should I do

Suppose I have the following list:
m=[1,2,[1],1,2,[1]]
I wish to take away all duplicates. If it were not for the brackets inside the the list, then I could use:
m=list(set(m))
but when I do this, I get the error:
unhashable type 'set'.
What command will help me remove duplicates so that I could only be left with the list
m=[1,2,[1]]
Thank you
You can do something along these lines:
m=[1,2,[1],1,2,[1]]
seen=set()
nm=[]
for e in m:
try:
x={e}
x=e
except TypeError:
x=frozenset(e)
if x not in seen:
seen.add(x)
nm.append(e)
>>> nm
[1, 2, [1]]
From comments: This method preserves the order of the original list. If you want the numeric types in order first and the other types second, you can do:
sorted(nm, key=lambda e: 0 if isinstance(e, (int,float)) else 1)
The first step will be to convert the inner lists to tuples:
>> new_list = [tuple(i) if type(i) == list else i for i in m]
Then create a set to remove duplicates:
>> no_duplicates = set(new_list)
>> no_duplicates
{1, 2, (1,)}
and you can convert that into list if you wish.
For a more generic solution you can serialize each list item with pickle.dumps before passing them to set(), and then de-serialize the items with pickle.loads:
import pickle
m = list(map(pickle.loads, set(map(pickle.dumps, m))))
If you want the original order to be maintained, you can use a dict (which has become ordered since Python 3.6+) instead of a set:
import pickle
m = list(map(pickle.loads, {k: 1 for k in map(pickle.dumps, m)}))
Or if you need to be compatible with Python 3.5 or earlier versions, you can use collections.OrderedDict instead:
import pickle
from collections import OrderedDict
m = list(map(pickle.loads, OrderedDict((k, 1) for k in map(pickle.dumps, m))))
result = []
for i in m:
flag = True
for j in m:
if i == j:
flag = False
if flag:
result.append(i)
Result will be: [1,2,[1]]
There are ways to make this code shorter, but I'm writing it more verbosely for readability. Also, note that this method is O(n^2), so I wouldn't recommend for long lists. But benefits is the simplicity.
Simple Solution,
m=[1,2,[1],1,2,[1]]
l= []
for i in m:
if i not in l:
l.append(i)
print(l)
[1, 2, [1]]
[Program finished]

Resources