I have a dictionary similar to this
x ={'1': [['a','b'],['ac','d']], '2' : [['p','qa'],['r','s']]}
And I would like to access the individual strings i.e. a,b etc , compare if it has "a" in it, delete those.
The main question is - how do I access the strings? How do I change it?
I tried using nested loops, but was unable to change, as I guess assignment stmts do not work that way.
Any idea how to proceed with such situation?
Edit : The naive approach I used -
for item in x:
for ele in x[item]:
for i in ele:
i = #assign new value here using regex comparison
But when I try to print x after this, it stays same.
Obviously. assignment statements do not work this way. Any idea about how should I access the elements to change it?
>>> x ={'1': [['a','b'],['ac','d']], '2' : [['p','qa'],['r','s']]}
>>> for key in x:
... for n, item in enumerate(x[key]):
... x[key][n] = list(filter(lambda l: 'a' not in l, x[key][n]))
...
>>> x
{'2': [['p'], ['r', 's']], '1': [['b'], ['d']]}
In your example,
for item in x:
for ele in x[item]:
for i in ele:
i = #assign new value here using regex comparison
i is a copy of the string in ele, so assigning to it has no effect on the original. You need to modify the list ele. Possibly, ele[ele.index(i)] = #whatever. Note, however, that this will not work correctly if you have identical values in the list. It will only change the first one.
Not sure what you're actually trying to do, but it may be easier to use a list comprehension, at least for the innermost list. This will allow you to change each element of the innermost list. Perhaps,
for item in x.values():
for ele in item:
ele[:] = [#whatever for i in ele]
where ele[:] is needed to change the original inner list (just ele won't work), and I used the more Pythonic x.values() when we actually wanted the values, not the keys.
Related
I have a dictionary with its values being a list, e.g. A = {'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]}, and I want to check if the value 2 exist in the values of the dictionary. Since A.values() will return a list with each element being a list, so doing 2 in A.values() will always return false. Is there away to solve this without looping over each value?
You'll have to loop some way, either yourself or with built-in functionality. Here's an explicit loop over the values and a "hidden" loop using in.
any(2 in v for v in A.values())
Note this only goes as far as necessary, stops the search as soon as it finds the value. And only takes O(1) space.
one easy was is to flatten the list of values:
A = {'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]}
print(2 in [item for sublist in list(A.values()) for item in sublist])
True
You can try this.
A = {'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]}
for key in A:
if 2 in A.get(key):
print(True)
You can loop through it by key and check its value by .get() function
I have a variable = 'P13804'
I also have a list like this:
['1T9G\tA\t2.9\tP11310\t241279.81', '1T9G\tS\t2.9\tP38117\t241279.81', '1T9G\tD\t2.9\tP11310\t241279.81', '1T9G\tB\t2.9\tP11310\t241279.81', '1T9G\tR\t2.9\tP13804\t241279.81', '1T9G\tC\t2.9\tP11310\t241279.81']
You can see, if you split each item in this list up by tab, that the third item in each sub-list of this list is sometimes 'P11310' and sometimes is 'P13804'.
I want to remove the items from the list, where the third item does not match my variable of interest (i.e. in this case P13804).
I know a way to do this is:
var = 'P13804'
new_list = []
for each_item in list1:
split_each_item = each_item.split('\t')
if split_each_item[3] != var:
new_list.append(each_item)
print(new_list)
In reality, the lists are really long, and i have a lot of variables to check. So I'm wondering does someone have a faster way of doing this?
It is generally more efficient in Python to build a list with a comprehension than repeatedly appending to it. So I would use:
var = 'P13804'
new_list = [i for i in list1 if i.split('\t')[2] == var]
According to timeit, it saves more or less 20% of the elapsed time.
for example if I had
array=[["A",1],["B",2],["C",1]]
is there any way I can find ["A",1] by just looking for "A"? I'm trying to use this in a situation where the first thing in the array is unique so there's no point in looking at the second, also I have no way of knowing what the second variable is
Iterate over items present inside the outer list and check that the first element of inner list satisfies a particular condition.
>>> a=[["A",1],["B",2],["C",1]]
>>> next(i for i in a if i[0] == 'A')
['A', 1]
>>> [i for i in a if i[0] == 'A']
[['A', 1]]
If you're in control of the datatype, depending on whate else you're doing with this object, a dictionary may be a better choice for this:
Rather than
array=[["A",1],["B",2],["C",1]]
use
d={"A":1, "B":2, "C":1}
Then you can access the element associated with "A" simply with
>> d["A"]
1
If you want to transform your list into a dictionary:
d = dict(array)
I have a list of strings, and calling a function on each string which returns a string. The thing I want is to update the string in the list. How can I do that?
for i in list:
func(i)
The function func() returns a string. i want to update the list with this string. How can it be done?
If you need to update your list in place (not create a new list to replace it), you'll need to get indexes that corresponds to each item you get from your loop. The easiest way to do that is to use the built-in enumerate function:
for index, item in enumerate(lst):
lst[index] = func(item)
You can reconstruct the list with list comprehension like this
list_of_strings = [func(str_obj) for str_obj in list_of_strings]
Or, you can use the builtin map function like this
list_of_strings = map(func, list_of_strings)
Note : If you are using Python 3.x, then you need to convert the map object to a list, explicitly, like this
list_of_strings = list(map(func, list_of_strings))
Note 1: You don't have to worry about the old list and its memory. When you make the variable list_of_strings refer a new list by assigning to it, the reference count of the old list reduces by 1. And when the reference count drops to 0, it will be automatically garbage collected.
First, don't call your lists list (that's the built-in list constructor).
The most Pythonic way of doing what you want is a list comprehension:
lst = [func(i) for i in lst]
or you can create a new list:
lst2 = []
for i in lst:
lst2.append(func(i))
and you can even mutate the list in place
for n, i in enumerate(lst):
lst[n] = func(i)
Note: most programmers will be confused by calling the list item i in the loop above since i is normally used as a loop index counter, I'm just using it here for consistency.
You should get used to the first version though, it's much easier to understand when you come back to the code six months from now.
Later you might also want to use a generator...
g = (func(i) for i in lst)
lst = list(g)
You can use map() to do that.
map(func, list)
I want to check if a value is in a list, no matter what the case of the letters are, and I need to do it efficiently.
This is what I have:
if val in list:
But I want it to ignore case
check = "asdf"
checkLower = check.lower()
print any(checkLower == val.lower() for val in ["qwert", "AsDf"])
# prints true
Using the any() function. This method is nice because you aren't recreating the list to have lowercase, it is iterating over the list, so once it finds a true value, it stops iterating and returns.
Demo : http://codepad.org/dH5DSGLP
If you know that your values are all of type str or unicode, you can try this:
if val in map(str.lower, list):
...Or:
if val in map(unicode.lower, list):
If you really have just a list of the values, the best you can do is something like
if val.lower() in [x.lower() for x in list]: ...
but it would probably be better to maintain, say, a set or dict whose keys are lowercase versions of the values in the list; that way you won't need to keep iterating over (potentially) the whole list.
Incidentally, using list as a variable name is poor style, because list is also the name of one of Python's built-in types. You're liable to find yourself trying to call the list builtin function (which turns things into lists) and getting confused because your list variable isn't callable. Or, conversely, trying to use your list variable somewhere where it happens to be out of scope and getting confused because you can't index into the list builtin.
You can lower the values and check them:
>>> val
'CaSe'
>>> l
['caSe', 'bar']
>>> val in l
False
>>> val.lower() in (i.lower() for i in l)
True
items = ['asdf', 'Asdf', 'asdF', 'asjdflk', 'asjdklflf']
itemset = set(i.lower() for i in items)
val = 'ASDF'
if val.lower() in itemset: # O(1)
print('wherever you go, there you are')