Basically what I want is this:
>>> a = ["a","a","b","c","c","c","d","e","f"]
>>> b = ["a","b","c","d","e","f"]
>>> #Do something, something like a - b
>>> result = ["a","c","c"]
Reason I want to do this, I am joining a bunch of lists of preferences and want to find which one is common among a lot of lists. The more times they occur in list a (because more lists have that element) the more weight I put towards that
You are looking for multisets, really. Use collections.Counter(), the Python implementation of a multiset:
from collections import Counter
acount = Counter(a)
bcount = Counter(b)
result = list((acount - bcount).elements())
Demo:
>>> from collections import Counter
>>> a = ['a', 'a', 'b', 'c', 'c', 'c', 'd', 'e', 'f']
>>> b = ['a', 'b', 'c', 'd', 'e', 'f']
>>> Counter(a) - Counter(b)
Counter({'c': 2, 'a': 1})
>>> list((Counter(a) - Counter(b)).elements())
['a', 'c', 'c']
You may want to retain the Counter() instances however; but if you need it the Counter.elements() method generates a sequence of elements times their count to produce your desired output again.
All you need to do is iterate over each element of b and remove it from a.
Without using multisets, you could iterate over the elements of b and remove from a. Remove only removes a single instance of the element not all instances of equivalent elements. You could do this in succinctly using map.
result = a[:] #copy a
map(result.remove, b) #remove elements of b from a
Related
I want to insert a word alphabetically into a list. Originally I would append the word I'm adding to the end of the list and then sort the list, but I am not allowed to use the sort() function.
Is there a way to do this through a function?
Based of of #SheshankS.'s answer. A function to do this for you:
def insert(item, _list):
for index, element in enumerate(_list):
if item < element: # in python, this automatically compares alphabetical precedence.
_list.insert(index, item)
return # exit out of the function since we already inserted
# if the item was not inserted, it must have the lowest precedence, so just append it
_list.append(item)
Note that since lists are mutable, this will actually mutate the given instance.
So, this:
someList = ["a", "b", "d"]
insert("c", someList)
Will actually change someList instead of just returning the new value.
Try doing this:
array = ["asdf", "bsdf", "kkkk", "zssdd"]
insertion_string = "zzat"
i = 0
for element in array:
if insertion_string < element:
array.insert(i, insertion_string)
break
i += 1
# if it is last one
if not insertion_string in array:
array.append(insertion_string)
print (array )
Repl.it = https://repl.it/repls/VitalAvariciousCodec
You did not say if you are allowed to use third-party modules, and you did not say if speed is a factor. If you want to add a new item to your sorted list quickly and you are allowed to use a module, use the SortedList class from sortedcontainers. This is a module included in many distributions of Python, such as Anaconda.
This will be simple and fast, even for large lists.
someList = SortedList(["a", "b", "d"])
someList.add("c")
print(someList)
The printout from that is
SortedList(['a', 'b', 'c', 'd'])
>>> import bisect
>>> someList = ["a", "b", "d"]
>>> bisect.insort(someList,'c')
>>> someList
['a', 'b', 'c', 'd']
>>>
If standard lib is allowed you can use bisect:
>>> import bisect
>>> lst = list('abcefg')
>>> for x in 'Adh':
... lst.insert(bisect.bisect(lst, x), x)
... print(lst)
...
['A', 'a', 'b', 'c', 'e', 'f', 'g']
['A', 'a', 'b', 'c', 'd', 'e', 'f', 'g']
['A', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
I would like to keep the first and last elements of a list, and exclude others that meet defined criteria without using a loop. The first and last elements may or may not have the criteria of elements being removed.
As a very basic example,
aList = ['a','b','a','b','a']
[x for x in aList if x !='a']
returns ['b', 'b']
I need ['a','b','b','a']
I can split off the first and last values and then re-concatenate them together, but this doesn't seem very Pythonic.
You can use slice assignment:
>>> aList = ['a','b','a','b','a']
>>> aList[1:-1]=[x for x in aList[1:-1] if x !='a']
>>> aList
['a', 'b', 'b', 'a']
Yup, it looks like dawg’s and jez’s suggested answers are the right ones, here. Leaving the below for posterity.
Hmmm, your sample input and output don’t match what I think your question is, and it is absolutely pythonic to use slicing:
a_list = ['a','b','a','b','a']
# a_list = a_list[1:-1] # take everything but the first and last elements
a_list = a_list[:2] + a_list[-2:] # this gets you the [ 'a', 'b', 'b', 'a' ]
Here's a list comprehension that explicitly makes the first and last elements immune from removal, regardless of their value:
>>> aList = ['a', 'b', 'a', 'b', 'a']
>>> [ letter for index, letter in enumerate(aList) if letter != 'a' or index in [0, len(x)-1] ]
['a', 'b', 'b', 'a']
Try this:
>>> list_ = ['a', 'b', 'a', 'b', 'a']
>>> [value for index, value in enumerate(list_) if index in {0, len(list_)-1} or value == 'b']
['a', 'b', 'b', 'a']
Although, the list comprehension is becoming unwieldy. Consider writing a generator like so:
>>> def keep_bookends_and_bs(list_):
... for index, value in enumerate(list_):
... if index in {0, len(list_)-1}:
... yield value
... elif value == 'b':
... yield value
...
>>> list(keep_bookends_and_bs(list_))
['a', 'b', 'b', 'a']
I'd like to join a list into a string by index in Python 3.3. I can do it for items the follow each other, but I would like to access it by index only.
this works:
list = ['A', 'B', 'C', 'D']
partList = "".join(list[1:3])
-> BC
But how can I achieve this (it doesn't work):
list = ['A', 'B', 'C', 'D']
partList = "".join(list[0,3])
-> AD
You can't slice lists into arbitrary chunks using slice notation. Probably your best bet for the general case is to use a list of indices to build a list comprehension.
mylist = ['A', 'B', 'C', 'D'] # the full list
indices = [0, 3] # the indices of myList that you want to extract
# Now build and join a new list comprehension using only those indices.
partList = "".join([e for i, e in enumerate(mylist) if i in indices])
print(partList) # >>> AD
As pointed out in the comments by DSM, if you're concerned with efficiency and you know your list of indices will be "friendly" (that is, it won't have any indices too big for the list you're cutting up), you can use a simpler expression without enumerate:
partList = "".join([mylist[i] for i in indices])
What you are intending to perform is not slicing but selecting.
The closest possibility, I can think of is to use operator.itemgetter
>>> from operator import itemgetter
>>> mylist = ['A', 'B', 'C', 'D']
>>> ''.join(itemgetter(0,3)(mylist))
'AD'
If you need to use a variable, then use a splat operator
index = (0,3)
''.join(itemgetter(*index)(mylist))
I am fairly new to python and I am trying to figure out how to find if the elements of a list equal a given string?
lists=["a","b",'c']
str1='abc'
I know it is probably easy, but I am having a hard time without using string methods.
Thanks,
DD
>>> l = ['a', 'b', 'c']
>>> l == list('abc')
True
But, if the order of items in the list can be arbitrary, you can use sets:
>>> l = ['c', 'b', 'a']
>>> set(l) == set('abc')
True
or:
>>> l = ['c', 'b', 'a']
>>> s = set(l)
>>> all(c in s for c in 'abc')
True
>>> lists=["a","b",'c']
>>> str1='abc'
>>> ''.join(lists) == str1
True
you can use .join to create a string from your list:
list = ['a', 'b', 'c']
strToComapre = ''.join(list1)
Now you can check if strToComapre is "in" the original str:
if strToCompare in originalStr:
print "yes!"
If you want a pure compare use:
if strToCompare == originalStr:
print "yes! it's pure!"
There are lots of options in python i'll add some other useful posts:
Compare string with all values in array
http://www.decalage.info/en/python/print_list
Given input:
list = [['a']['a', 'c']['d']]
Expected Ouput:
mylist = a,c,d
Tried various possible ways, but the error recieved is TypeError: list indices must be integers not tuple.
Tried:
1.
k= []
list = [['a']['a', 'c']['d']]
#k=str(list)
for item in list:
k+=item
print k
2.
print zip(*list)
etc.
Also to strip the opening and closing parenthesis.
What you want is flattening a list.
>>> import itertools
>>> l
[['a'], ['a', 'c'], ['d']]
>>> res = list(itertools.chain.from_iterable(l))
>>> res
['a', 'a', 'c', 'd']
>>> set(res) #for uniqify, but doesn't preserve order
{'a', 'c', 'd'}
Edit: And your problem is, when defining a list, you should seperate values with a comma. So, not:
list = [['a']['a', 'c']['d']]
Use commas:
list = [['a'], ['a', 'c'], ['d']]
And also, using list as a variable is a bad idea, it conflicts with builtin list type.
And, if you want to use a for loop:
l = [['a'], ['a', 'c'], ['d']]
k = []
for sublist in l:
for item in sublist:
if item not in k: #if you want list to be unique.
k.append(item)
But using itertools.chain is better idea and more pythonic I think.
While utdemir's answer does the job efficiently, I think you should read this - start from "11.6. Recursion".
The first examples deals with a similar problem, so you'll see how to deal with these kinds of problems using the basic tools.