I have a list
a=['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
I am trying to find largest element in the list with no duplicates.
For example script should return "country" as it doesn't have any duplicates.
Please help
You could also use collections.Counter for this:
from collections import Counter
a = ['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
a = set(a)
no_dups = []
for word in a:
counts = Counter(word)
if all(v == 1 for v in counts.values()):
no_dups.append(word)
print(max(no_dups, key = len))
Which follows this procedure:
Converts a to a set, since we only need to look at a word once, just in case a contains duplicates.
Creates a Counter() object of each word.
Only appends words that have a count of 1 for each letter, using all().
Get longest word from this resultant list, using max().
Note: This does not handle ties, you may need to do further work to handle this.
def has_dup(x):
unique = set(x) # pick unique letters
return any([x.count(e) != 1 for e in unique]) # find if any letter appear more than once
def main():
a = ['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
a = [e for e in a if not has_dup(e)] # filter out duplicates
chosen = max(a, key=len) # choose with max length
print(chosen)
if __name__ == '__main__':
main()
Related
Curious if there is any way to do something similar to this.
Dictionary = {"item":1,"item2":[1,2,3,4]}
for keys,values in Dictionary.items():
if values == list():
print(values[0:3])
With the resulting outcome of
1
2
3
4
Sure, there is:
Dictionary = {"item": 1, "item2": [1,2,3,4]}
for values in Dictionary.values():
if type(values) == list:
for item in values:
print(item, end=' ')
results is a list within a list with the data as shown in the results section. I am hoping to achieve a dictionary within a dictionary as shown in the results portion.
input:
results = [['abc','12'3,'1123','qwe', 'asd'],['abc','123,'1123','qwe', '123'],['abc','123','1123','ewq','zxc'], ['bcd','123','1123','ewq','zxc'], ['bcd','123','1123','ewq','zxc]]
Code:
report_dict = dict()
axis_list = []
results = self.report_data(conn)
for row in results:
try:
report_dict[row[0]] = {}
report_dict[row[0]][row[3]] = row[1]
except IndexError:
None
print(report_dict)
Result:
report_dict = { 'abc': {'qwe':['asd','123'], 'ewq':['zxc']}, 'bcd' : {'qwe':['asd'], 'ewq':['zxc']} …..}
Please note there are duplicate keys in the dataset.
you could do:
d = {}
for i in results:
if not d.get(i[0],0):
d[i[0]] = {}
if not d[i[0]].get(i[3],0):
d[i[0]][i[3]] = []
d[i[0]][i[3]].append(i[4])
d
{'abc': {'qwe': ['asd', '123'], 'ewq': ['zxc']}, 'bcd': {'ewq': ['zxc', 'zxc']}}
The following is a solution to your immediate question with tuples in the list:
from collections import defaultdict
report_dict = defaultdict(list)
# results = self.report_data(conn)
results = [["abc",123,1123,"qwe", "asd"],["abc",123,1123,"ewq","zxc"], ["bcd",123,1123,"ewq","zxc"], ["bcd",123,1123,"ewq","zxc"]]
for row in results:
try:
report_dict[row[0]].append((row[3], row[1]))
except IndexError:
None
print(report_dict)
Result: defaultdict(<class 'list'>, {'abc': [('qwe', 123), ('ewq', 123)], 'bcd': [('ewq', 123), ('ewq', 123)]})
you can also change it to a dictionaries in the list with the following line
report_dict[row[0]].append({row[3]: row[1]})
Result: defaultdict(<class 'list'>, {'abc': [{'qwe': 123}, {'ewq': 123}], 'bcd': [{'ewq': 123}, {'ewq': 123}]})
I have a list with values occurring multiple times. I want to loop over the list and check if value is occurring very first time.
For eg: Let's say I have a one list like ,
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
Now, at every first occurrence of element, I want to perform some set of tasks.
How to get the first occurrence of element?
Thanks in Advance!!
Use a set to check if you had processed that item already:
visited = set()
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
for e in L:
if e not in visited:
visited.add(e)
# process first time tasks
else:
# process not first time tasks
You can use unique_everseen from itertools recipes.
This function returns a generator which yield only the first occurence of an element.
Code
from itertools import filterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
Example
lst = ['a', 'a', 'b', 'c', 'b']
for x in unique_everseen(lst):
print(x) # Do something with the element
Output
a
b
c
The function unique_everseen also allows to pass a key for comparison of elements. This is useful in many cases, by example if you also need to know the position of each first occurence.
Example
lst = ['a', 'a', 'b', 'c', 'b']
for i, x in unique_everseen(enumerate(lst), key=lambda x: x[1]):
print(i, x)
Output
0 a
2 b
3 c
Why not using that?
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
for idxL, L_idx in enumerate(L):
if (L.index(L_idx) == idxL):
print("This is first occurence")
For very long lists, it is less efficient than building a set prior to the loop, but seems more direct to write.
I need to print only duplicate numbers in a list and need to multiply by count. the code is as follows , the output should be ,
{1:3, 2:2, 3:2} need to multiply each numbers by count and print as separate answers:
answer1 = 1*3, answer2 = 2*2 , answer3 = 3*2
Current attempt:
from collections import Counter
alist = [1,2,3,5,1,2,1,3,1,2]
a = dict(Counter(a_list))
print(a)
Counter already does the heavy lifting. So for the rest, what about generating a list of the values occuring more than once, formatting the output as you wish ? (sorting the keys seems necessary so indexes match the keys order):
from collections import Counter
a_list = [1,2,3,5,1,2,1,3,1,2]
a = ["{}*{}".format(k,v) for k,v in sorted(Counter(a_list).items()) if v > 1]
print(a)
result:
['1*4', '2*3', '3*2']
If you want the numerical result instead:
a = [k*v for k,v in sorted(Counter(a_list).items()) if v > 1]
result (probably more useful):
[4, 6, 6]
Assigning to separate variables (answer1,answer2,answer3 = a) is not a very good idea. Keep a indexed list
So the input is word and I want to know if a or b comes first.
I can use a_index = word.find('a') and compare this to b_index = word.find('b') and if a is first, a is first is returned. But if b isn't in word, .find() will return -1, so simply comparing b_index < a_index would return b is first. This could be accomplished by adding more if-statements, but is there a cleaner way?
function description:
input: word, [list of characters]
output: the character in the list that appears first in the word
Example: first_instance("butterfly", ['a', 'u', 'e'] returns u
You can create a function that takes word and a list of chars - convert those chars into a set for fast lookup and looping over word take the first letter found, eg:
# Chars can be any iterable whose elements are characters
def first_of(word, chars):
# Remove duplicates and get O(1) lookup time
lookup = set(chars)
# Use optional default argument to next to return `None` if no matches found
return next((ch for ch in word if ch in lookup), None)
Example:
>>> first_of('bob', 'a')
>>> first_of('bob', 'b')
'b'
>>> first_of('abob', 'ab')
'a'
>>> first_of("butterfly", ['a', 'u', 'e'])
'u'
This way you're only ever iterating over word once and short-circuit on the first letter found instead of running multiple finds, storing the results and then computing the lowest index.
Make a list without the missing chars and then sort it by positions.
def first_found(word, chars):
places = [x for x in ((word.find(c), c) for c in chars) if x[0] != -1]
if not places:
# no char was found
return None
else:
return min(places)[1]
In any case you need to check the type of the input:
if isinstance(your_input, str):
a_index = your_input.find('a')
b_index = your_input.find('b')
# Compare the a and b indexes
elif isinstance(your_input, list):
a_index = your_input.index('a')
b_index = your_input.index('b')
# Compare the a and b indexes
else:
# Do something else
EDIT:
def first_instance(word, lst):
indexes = {}
for c in lst:
if c not in indexes:
indexes[c] = word.find(c)
else:
pass
return min(indexes, key=indexes.get)
It will return the character from list lst which comes first in the word.
If you need to return the index of this letter then replace the return statement with this:
return min_value = indexes[min(indexes, key=indexes.get)]