Unpacking iterables in Python3? - list

Why is this returning in sort_tup_from_list for key, val in tup: ValueError: not enough values to unpack (expected 2, got 1)
# list with tuples
lst = [("1", "2"), ("3", "4")]
# sorting list by tuple val key
def sort_tup_from_list(input_list):
tmp = []
print(tup)
for tup in input_list:
for key, val in tup:
tmp.append((val, key))
tmp.sort(reverse=True)
return tmp
print(sort_tup_from_list(lst))
When I comment out second for loop, it prints tuple:
lst = [("1", "2"), ("3", "4")]
def sort_tup_from_list(input_list):
tmp = []
for tup in input_list:
print(tup)
# for key, val in tup:
# tmp.append((val, key))
# tmp.sort(reverse=True)
return tmp
print(sort_tup_from_list(lst))
Output:
('1', '2')
('3', '4')
[]
So, tuples are there. Why are they not unpacking themselfs?

Your second for loop is looping through items in the tuple, but you're grabbing both of the items in it. I think this is what you want:
# list with tuples
lst = [("1", "2"), ("3", "4")]
# sorting list by tuple val key
def sort_tup_from_list(input_list):
tmp = []
print(tmp)
for key,val in input_list:
tmp.append((val, key))
tmp.sort(reverse=True)
return tmp
print(sort_tup_from_list(lst))

Related

How to create two lists/or more, with one list?

lst =["1","2","","3","4","5","","6"]
Given the list above, how do I split the list an create another list whenever I find ""(the empty quotation marks alone)?
lst =["1","2","","3","4","5","","6"]
lst2 = []
for a in lst:
if a == "":
continue
lst2.append(int(a))
print(lst2)
Output:[1, 2, 3, 4, 5, 6]
Expected output:
lst2 = [["1","2"],["3","4","5"],["6"]]
lst =["1","2","","3","4","5","","6"]
arr = []
new_lst = []
for i in lst:
if i == "":
arr.append(new_lst)
new_lst = []
else:
new_lst.append(i)
if len(new_lst) > 0:
arr.append(new_lst)
print(arr)

How to implement a dictionary using a Map

I'm trying to implement a dictionary but the Map.put function is not adding the new element to the map instead it is giving me a new map with the last (key, value} inserted I also tried Map.put_new it did not work
def someFunction(array) do
dict = %{}
Enum.each(array, fn item ->
if (Map.has_key?(dict, item)) do
dict = %{dict | item => (dict[item] + 1)}
else
dict = Map.put(dict , item, 1)
end
end)
end
The way elixir does variable scopes, you can't set dict from inside your Enum.each/2. Instead what you need to do is pass dict as an accumulator while enumerating array.
dict =
Enum.reduce(array, %{}, fn item, dict ->
if (Map.has_key?(dict, item)) do
%{dict | item => (dict[item] + 1)}
else
Map.put(dict , item, 1)
end
end)
You can also use Map.update/4 to improve your reducer.
dict = Enum.reduce(array, %{}, fn item, dict -> Map.update(dict, item, 1, &(&1 + 1)) end)
But there's actually a built-in function since Elixir 1.10, Enum.frequencies/1.
dict = Enum.frequencies(array)

convert a list containing sublist and tuples into a flat list

'a = [1,2,[12,5,(6,7,9)],[34,56]]
lambda l: [item for sublist in l for item in sublist]
ab = lambda a: [item for sublist in a for item in sublist]
print(ab(a))'
I want output like this [1,2,12,5,6,7,9,34,56]
Enjoy:
def convert(lst):
if all(not isinstance(e, (list, tuple)) for e in lst):
return lst[:]
else:
result = []
for e in lst:
if isinstance(e, (list, tuple)):
converted = convert(e)
result.extend(converted)
else:
result.append(e)
return result
I treat this as a text processing job.First convert the pass-in list into the string representation, then split the string into small parts each contains a element, finally i use a empty list receive these fresh elements.Here is my code snippt:
def simpleL(complexL):
a =repr(complexL).split(',')
c=[]
for i in a:
element =i.strip('[()] ')
if element.isdigit():
c.append(int(element))
return c
output = []
def uni_lst(lst):
if type(lst) in [list, tuple]:
for x in lst:
if type(x) in [list, tuple]:
uni_lst(x)
else:
output.append(x)
return output
Above code will make a single list from any type of list or tuple.

Python. <Remove Element> in a list

Title:
172. Remove Element
Description:
Given an array and a value, remove all occurrences of that value in place and return the new length.
The order of elements can be changed, and the elements after the new length don't matter.
My Answer:
On LintCode
def removeElement(self, A, elem):
# write your code here
if A == []:
return A
if elem in A:
sortedA = sorted(A)
li = []
for i in xrange(len(sortedA)):
if sortedA[i] == elem:
li += [i]
newLength = sortedA[:min(li)] + sortedA[max(li)+1:]
return newLength
else:
return A
On my mac
A = [0,4,4,0,0,2,4,4]
elem = 4
def sss(A, elem):
if A == []:
return A
if elem in A:
print A
sortedA = sorted(A)
print sortedA
li = []
for i in xrange(len(sortedA)):
# print type(i)
if sortedA[i] == elem:
li += [i]
print li
newLength = sortedA[:min(li)] + sortedA[max(li)+1:]
print newLength
return newLength
else:
return A
print sss(A, elem)
This answer On my mac work's good, but On LintCode doesn't accept.
Why not use a list comprehension to filter out the unwanted elements?
class Solution:
def removeElement(self, A, elem):
A[:] = [item for item in A if item != elem]
return len(A)
The key here is the slice notation on the left hand side of the assignment. This makes it an "in place" operation, so the original list A is mutated, rather than a copy being made.
Example usage:
>>> l = [1, 2, 3, 4, 4, 5, 4, 10, 11, 4]
>>> len(l)
10
>>> Solution().removeElement(l, 4)
6
>>> l
[1, 2, 3, 5, 10, 11]
>>> len(l)
6
Although this is an old post, yet would like to add the different approaches I tried. Time Complexity is O(n) in all cases.
Method I: Override the elements if they are not val (Logical Approach)
def removeElement(self, nums: List[int], val: int) -> int:
i : int = 0 # This will be an index pointer & will provide the sixe at the end
for j in range(len(nums)):
if nums[j] != val: # if the values are not same
nums[i] = nums[j] # Override the value at location i
i+=1
return i
Method II: Override the val with last array element (Logical Approach)
def removeElement(self, nums: List[int], val: int) -> int:
i: int = 0
n: int = len(nums)
while(i<n):
if(nums[i] == val):
# Replace the element with last array element & reduce the array size by 1
nums[i] = nums[n-1]
n -=1
else:
i +=1
return n
Method III -- Improved form of Method 2 (Python way)
def removeElement(self, nums: List[int], val: int) -> int:
i : int = 0
n : int = len(nums)
while i< n :
print(i, nums, n)
if val in nums[:n]:
i = nums.index(val,0,n)
nums[i] = nums[n-1]
n -=1
else:
break
return n
Method IV -- Python way
def removeElement(self, nums: List[int], val: int) -> int:
nums[:] = [x for x in nums if x !=val]
return len(nums)
All of them have an average runtime of around 36ms and memory utilization around 13.8MB.

how to get the list of the lists?

I have a problem like that:
list = ['a1',['b1',2],['c1',2,3],['d1',2,3,4]]
I want to get a new list like that
new_list['a1','b1','c1','d1']
I do like this:
lst = ['a1',['b1',2],['c1',2,3],['d1',2,3,4]]
for item in lst:
print(item)
result is:
a1
['b1', 2]
['c1', 2, 3]
['d1', 2, 3, 4]
But I want the first element of each result
The best answer is like this :
my_list = list()
lst = ['a1',['b1',2],['c1',2,3],['d1',2,3,4]]
for element in lst:
if type(element)==type('string'):
my_list.append(element)
else:
my_list.append(element[0])
print(my_list)
Thank you!
Do it as below:
>>> my_list = list()
>>> lst = ['a1',['b1',2],['c1',2,3],['d1',2,3,4]]
>>> for element in lst:
if type(element)==type('string'):
my_list.append(element)
else:
my_list.append(element[0])
It will produce:
>>> my_list
['a1', 'b1', 'c1', 'd1']
>>>
As you see above, first I created a list (named my_list) and then checked each elements of your list. If the element was a string, I added it to my_list and otherwise (i.e. it is a list) I added the first element of it to my_list.
I would do
res = []
for x in the_list:
if x is Array:
res.append(x[0])
else:
res.append(x)