This question already has answers here:
How do I sort a dictionary by value?
(34 answers)
Closed 5 years ago.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def deleteDuplicates(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head == None:
return None
start = head
prev = head.val
a = {prev:1}
#o = [prev]
head = head.next
while head != None:
if head.val == prev:
a[prev] += 1
else:
prev = head.val
a[prev] = 1
#o.append(prev)
head = head.next
b = ListNode(0)
ans = b
for i in a: # can use for i in o
if a[i] == 1:
c = ListNode(i)
b.next = c
b = b.next
return ans.next
I am trying to remove duplicate items from a sorted linked list, eg.[1,2,3,3,4,4,5,6,6,6] -> [1,2,5]. Can someone walk through the code and tell me what will be the final value of a is for the linked list 2->1->None. It should be {2:1, 1:1} but answer comes out to be {1:1, 2:1}...why?
dict object doesn't remember the order of elements which are added to the dictionary. If you want to preserve the ordering of the elements you can use OrderedDict.
O(N) option using groupby
>>> from itertools import groupby
>>> [k for k,g in groupby([1,2,3,3,4,4,5,6,6,6]) if len(list(g)) == 1]
[1, 2, 5]
Try the following:
>>> l = [1,2,3,3,4,4,5,6,6,6]
>>> [i for i in l if l.count(i) == 1]
This preserves the order of items in l.
Here's an approach in O(n) time (in Python 3), regardless of whether the list is sorted.
>>> lst = [1, 2, 3, 3, 4, 4, 5, 6, 6, 6]
>>> unique = {}
>>> for item in lst:
... if item in unique:
... unique[item] += 1
... else:
... unique[item] = 1
...
>>> [k for k, v in unique.items() if v == 1]
[1, 2, 5]
The statement for item in lst: ... is O(n).
The expression item in unique is O(1).
The statement unique[item] = 1 is O(1), and so is unique[item] += 1.
The expression [k for k, v in unique.items() if v == 1] is O(n).
So, calculating the time complexity of the for statement:
O(n) * (O(1) + max(O(1), O(1)))
O(n) * (O(1) + O(1))
O(n) * O(1)
O(n)
Add that to the time complexity of the list comprehension, and you have O(n) + O(n), which is O(2n). Drop the constant, and you have O(n).
This answer assumes that all you want to do is to create another list, only keeping the values that occur once.
One way of doing it would be to use groupby from itertools and then filter based on the length of each group.
# Assuming 's' holds our list
[i for i,k in itertools.groupby(s) if len(list(k)) == 1]
EDIT Reading your question again, it seems this solution might not work, unless the linked list type you're using conforms to the iterator protocol. At any rate, it certainly won't produce a list as output, although you could replace the list comprehension with a generator expression and build a linked list from that.
Related
How do we calculate with having both int element and list of list element.
def minelementNested(list):
minele = list[0]
sumele = 0
count = 0
for i in list1:
if type(i) is int:
sumele = sumele+i
if i < minele:
minele = i
count = count +1
else:
sumele += sum(i)
count = count + len(i)
else_min = min(i)
if else_min < minele:
minele = else_min
avg = sumele/count
print(avg)
return minele
list1 = [23,24,[10,11,12],56,85,[34,45,6]]
minelementNested(list1)
Is there any other way to do this?
or can we convert the individual int element to list and go ahead with list comprehension.
please suggest.
Thank you.
If you only have one level of nested list to worry about, you can do this as a one-liner that normalizes the nested list to a 2D list of lists of ints, and then unpacks it in a nested generator:
>>> nums = [23,24,[10,11,12],56,85,[34,45,6]]
>>> min(n for i in nums for n in (i if isinstance(i, list) else [i]))
6
If you have arbitrary levels of nesting, use a recursive function:
>>> def nested_min(arr):
... if isinstance(arr, int):
... return arr
... return min(nested_min(i) for i in arr)
...
>>> nested_min(nums)
6
>>> nested_min([10, 11, 12, [[1, 2], 3, 4], 5])
1
This question already has answers here:
How do I count the occurrences of a list item?
(29 answers)
Closed 4 years ago.
For example
MyList=[a,a,a,c,c,a,d,d,d,b]
Returns
[4,2,3,1]
from collections import Counter
MyList=['a','a','a','c','c','a','d','d','d','b']
Counter(MyList).values() # Counts's the frequency of each element
[4, 2, 1, 3]
Counter(MyList).keys() # The corresponding elements
['a', 'c', 'b', 'd']
just do it with dictionary :
counter_dict = {}
for elem in MyList:
if elem in counter_dict.keys():
counter_dict[elem] += 1
else :
counter_dict[elem] = 1
at the end you have a dictionary with key with key , which is the element in the list , and value which is the number of appearances.
If you need only a list:
# Your list
l1 = [1,1,2,3,1,2]
# Set will give you each element from l1 without duplicates
l2 = set(l1)
# Let`s see how set look
#print(l2)
# Create new empty list
l3 = []
# Use for loop to find count of each element from set and store that in l3
for i in l2:
k = l1.count(i)
l3.append(k)
# Check how l3 now looks like
print(l3)
Return:
[3, 2, 1]
First you should change your list elements to a string type:
my_list = ['a','a','a','c','c','a','d','d','d','b']
Because a, b, c or d without quote(') don't represent any type,so then you'll get error.
Try to use python dictionary, as follows:
result ={}
for each in my_list:
result.setdefault(each, 0)
result[each] += 1
print result.values()
Then this would be the output:
[4,2,3,1]
A first try would be doing this:
occurrencies = {n:a.count(n) for n in set(a)}
This returns a dictionary which has the element as key, and its occurrences as value. I use set to avoid counting elements more than once.
This is not a one-pass approach and it has quadratic complexity in time, hence this could be really slow.
Here's a way you could do to get the same result with one pass, linear complexity:
def count_occurrencies(inputArray):
result = {}
for element in inputArray:
if element not in result:
result[element] = 1
else:
result[element] += 1
return result
I am new to python and SO. I want to multiply each element of lists in a list of lists to another list lying in the same list of lists and compare it with a reference value. This will be more clear with an example:
for L = [[1,2,3,4,5,10],[3,2,4,1,5,10]] ##there can be more than 2 lists in this list of lists
I want only those pairs whose product results in 10.
Out: L = [[1,10],[2,5]]
Edit: I prefer a method without any imports, since I am doing this for building logic and my editor doesn't contain any modules to import. Also, if there are more than 2 lists in a list of lists For eg. there are 3 Lists in a list of lists: then I want triplets for that sake. ANd if 4 lists then I need quadruples.
Here's my code attempt as requested.
N = []
J = []
F = []
Z = []
S = []
O = []
num = input("Enter no. of elements in list")
print ('Enter numbers')
prod = 1
for i in range(int(num)):
n = input("num :")
N.append(int(n))
for x in N:
prod = prod*x
print (prod)
k = int(input("Enter no. of splits:"))
##d = [[] for x in xrange(k)]
##var_dict = []
for o in range(1,prod+1):
if prod%o == 0:
J.append(o)
print (J)
for g in range(k):
O.append(J*(k-1))
print (O)
for a in range(len(O)):
for b in range(len(O)):
if O[i]*O[i+1] == prod:
Z.extend(O)
##Z = [[a, b] for a in J for b in F if a*b == prod] ##imp
print (Z)
for e in Z:
if e not in S and sorted(e) not in S:
S.append(e)
print (S)
You can use itertools.product to find groups of numbers and filter them based on their product
>>> from itertools import product
>>> from functools import reduce
>>> lst = [[1,2,3,4,5,10],[3,2,4,1,5,10]]
>>> ans = [p for p in product(*lst) if reduce(lambda x,y:x*y, p) == 10]
>>> # Remove duplicates
>>> ans = list(map(list, set(map(frozenset, ans))))
>>> print (ans)
[[1, 10], [2, 5]]
>>>
In a comment you say you say you want code without any imports. Importing product from itertools and reduce do simplify and speed the code, but the job can be done without imports. Here is a recursive solution. I am not quite satisfied with this code but it seems to work and passes all my tests. I generalized the problem somewhat so that the input can have tuples or other sequences and not just lists.
def prod_is_target(seq_of_seqs, target):
"""Return a list of lists, where each sublist contains one member
of each input subsequence in order, and the product of those
members equals the target value. If there is no such list possible,
return None. If seq_of_seqs is empty, return an empty list if the
target is 1 and return None otherwise.
"""
if not seq_of_seqs: # if is empty sequence
return [] if target == 1 else None
result = []
for val in seq_of_seqs[0]:
if target % val: # skip if target is not a multiple of val
continue
prodlists = prod_is_target(seq_of_seqs[1:], target // val)
if prodlists is None: # skip if failed with later sublists
continue
if not prodlists: # if is empty list
result.append([val])
else:
for prodlist in prodlists:
result.append([val] + prodlist)
return result if result else None
print(prod_is_target([[1,2,3,4,5,10], [3,2,4,1,5,10]], 10))
The printout from that code is
[[1, 10], [2, 5], [5, 2], [10, 1]]
I'll leave it to you to remove what you consider to be duplicates. I can think of situations where you would want this full list, however.
I'm trying to teach myself a few sorting algorithms in python and I'm having a little bit of trouble with the output. I'm attempting to implement a counting sort algorithm and I've gotten this far:
def counting_sort(l):
nums = l
highest = max(nums) + 1
helper_list = [0] * highest
s_list = []
for i in range(len(nums)):
value = nums[i]
helper_list[value] += 1
for j in range(len(helper_list)):
s_list.append([j] * helper_list[j])
return s_list
Everything is going almost fine, but when I give an input such as [5, 2, 2, 3, 1, 2].
I get an output like: [[], [1], [2, 2, 2], [3], [5]].
You just have to change the "append" for "extend". The append function adds an element to your list, in this case, another list. The extend function concatenates your list with the one given as a parameter.
Your function should be like the following:
def counting_sort(elements):
highest = max(elements) + 1
helper_list = [0] * highest
s_list = []
for value in elements:
helper_list[value] += 1
for j in range(len(helper_list)):
s_list.extend([j] * helper_list[j])
return s_list
def counting_sort(unordered_list, k, desc=False):
'''
unordered_list is the input array to be sorted.
k is the range of non-negative key values.
desc lets the algorithm to sort the array in descending order.
time complexity is the sum of the times for two steps, O(n + k).
'''
count_list = [0] * k
for element in unordered_list:
count_list[element] += 1
if desc:
enumerator = reversed(list(enumerate(count_list)))
else:
enumerator = enumerate(count_list)
sorted_list = []
for idx, count in enumerator:
sorted_list += [idx] * count
return sorted_list
The problem is the line:
s_list.append([j] * helper_list[j])
This says to append a list ([j]*helper_list[j]) to s_list, adding that list as new element or s_list.
Instead, you want add one list onto the other, which can be done like so:
s_list.append += ([j] * helper_list[j])
What i have only removes duplicated items and sorts them. I need to remove one instance of every item and return a new list with the items in it. This is what i have:
def rem(nlst):
n = []
for x in nlst:
if x not in n:
n.append(x)
n.sort()
return n
This is what it should do:
>>> rem([4])
[]
>>> rem([4,4])
[4]
>>> rem([4, 1, 3, 2])
[]
>>> rem([2, 4, 2, 4, 4])
[2, 4, 4]
An easy implementation is to use collections.Counter:
def rem(iterable):
c = collections.Counter(iterable)
for k in c:
c[k] -= 1
return sorted(c.elements())
In Python versions before 2.7, collections.Counter is not available. You can use a set to record the items you already saw instead:
def rem(iterable):
result = []
seen = set()
for x in iterable:
if x in seen:
result.append(x)
else:
seen.add(x)
result.sort()
return result
A slight tweak to your code seems to work ok. Just added a variable to track the current value and only append a new one if you have already seen that value:
def rem(nlist):
n = []
nlist.sort()
cur = None
for x in nlist:
if x == cur:
n.append( x )
cur = x
return n
~