I want to do something like this:
myList = [10, 20, 30]
yourList = myList.append(40)
Unfortunately, list append does not return the modified list.
So, how can I allow append to return the new list?
See also: Why do these list operations (methods) return None, rather than the resulting list?
Don't use append but concatenation instead:
yourList = myList + [40]
This returns a new list; myList will not be affected. If you need to have myList affected as well either use .append() anyway, then assign yourList separately from (a copy of) myList.
In python 3 you may create new list by unpacking old one and adding new element:
a = [1,2,3]
b = [*a,4] # b = [1,2,3,4]
when you do:
myList + [40]
You actually have 3 lists.
list.append is a built-in and therefore cannot be changed. But if you're willing to use something other than append, you could try +:
In [106]: myList = [10,20,30]
In [107]: yourList = myList + [40]
In [108]: print myList
[10, 20, 30]
In [109]: print yourList
[10, 20, 30, 40]
Of course, the downside to this is that a new list is created which takes a lot more time than append
Hope this helps
Try using itertools.chain(myList, [40]). That will return a generator as a sequence, rather than allocating a new list. Essentially, that returns all of the elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted.
Unfortunately, none of the answers here solve exactly what was asked. Here is a simple approach:
lst = [1, 2, 3]
lst.append(4) or lst # the returned value here would be the OP's `yourList`
# [1, 2, 3, 4]
One may ask the real need of doing this, like when someone needs to improve RAM usage, do micro-benchmarks etc. that are, usually, useless. However, sometimes someone is really "asking what was asked" (I don't know if this is the case here) and the reality is more diverse than we can know of. So here is a (contrived because out-of-a-context) usage...
Instead of doing this:
dic = {"a": [1], "b": [2], "c": [3]}
key, val = "d", 4 # <- example
if key in dic:
dic[key].append(val)
else:
dic[key] = [val]
dic
# {'a': [1], 'b': [2], 'c': [3], 'd': [4]}
key, val = "b", 5 # <- example
if key in dic:
dic[key].append(val)
else:
dic[key] = [val]
dic
# {'a': [1], 'b': [2, 5], 'c': [3], 'd': [4]}
One can use the OR expression above in any place an expression is needed (instead of a statement):
key, val = "d", 4 # <- example
dic[key] = dic[key].append(val) or dic[key] if key in dic else [val]
# {'a': [1], 'b': [2], 'c': [3], 'd': [4]}
key, val = "b", 5 # <- example
dic[key] = dic[key].append(val) or dic[key] if key in dic else [val]
# {'a': [1], 'b': [2, 5], 'c': [3], 'd': [4]}
Or, equivalently, when there are no falsy values in the lists, one can try dic.get(key, <default value>) in some better way.
You can subclass the built-in list type and redefine the 'append' method. Or even better, create a new one which will do what you want it to do. Below is the code for a redefined 'append' method.
#!/usr/bin/env python
class MyList(list):
def append(self, element):
return MyList(self + [element])
def main():
l = MyList()
l1 = l.append(1)
l2 = l1.append(2)
l3 = l2.append(3)
print "Original list: %s, type %s" % (l, l.__class__.__name__)
print "List 1: %s, type %s" % (l1, l1.__class__.__name__)
print "List 2: %s, type %s" % (l2, l2.__class__.__name__)
print "List 3: %s, type %s" % (l3, l3.__class__.__name__)
if __name__ == '__main__':
main()
Hope that helps.
Just to expand on Storstamp's answer
You only need to do
myList.append(40)
It will append it to the original list,now you can return the variable containing the original list.
If you are working with very large lists this is the way to go.
You only need to do
myList.append(40)
It will append it to the original list, not return a new list.
I have a list of strings:
list1 = ['array1', 'array2', 'array3']
whose elements I would like to use as names of other lists, like (as conceptual example):
list1[0] = [1, 2, 3]
I know this assignation does not make any sense, but it is only to show what I need.
I have looked for this a lot but didn't find a handy example. If I understood properly, this is not the right way to do it, and better is to use dictionaries. But, I never used dictionaries yet, so I would need some examples.
aDict = { name: 42 for name in list1 }
This gives you:
{'array3': 42, 'array2': 42, 'array1': 42}
If you wanted it ordered:
from collections import OrderedDict
aDict = OrderedDict((name, 42) for name in list1)
Use a dictionary:
list1 = {'array1': [0, 1, 2], 'array2': [0, 3], 'array3': [1]}
and then access it like this:
list1['array1'] # output is [0, 1, 2]
To dynamically populate your dictionary:
list1 = {'array1': []}
list1['array1'].append(1)
You can do What you want with exec like this :
list1 = ['array1', 'array2', 'array3']
x=list1[1]
exec("%s = %d" % (x,2))
print array2
so result is :
2
But never use exec when you can use something much safer like dictionary, it can be dangerous !
In python if I do the following:
>>> list = [ 3, 2, 1]
>>> sorted_list = k.sort()
Then sorted_list is None and list is sorted:
>>> sorted_list = k.sort()
>>> print list, sorted_list
[1, 2, 3] None
However, if I do the following:
>>> list = [ 3, 2, 1]
>>> sorted_list = sorted(list)
Then list remains unsorted and sorted_list contains a copy of the sorted list:
>>> print list, sorted_list
[3, 2, 1] [1, 2, 3]
I am wondering if there is an equivalent for the update function for dictionaries.
That way I could do something like this:
def foo(a, b, extra={}):
bar = { 'first': a, 'second': b }
special_function(**updated(bar, extra))
normal_function(**bar)
rather than having to do something like this:
def foo(a, b, extra={}):
bar = { 'first': a, 'second': b }
special_bar = bar.copy()
special_bar.update(extra) # [1]
special_function(**special_bar)
normal_function(**bar)
[1] Yes I realize I could simply replace these two lines with extra.update(bar) but let's assume I want to retain extra as is for later on in the function.
I realize I could implement this myself thusly:
def updated(old_dict, extra={}):
new_dict = old_dict.copy()
new_dict.update(extra)
return new_dict
Or the following highly unreadable in-place statement:
special_function(**(dict(bar.items()+extra.items())))
But I was hoping there was something built in that I could already use.
You can simply use the built-in dict():
updated_dict = dict(old_dict, **extra_dict)
If you need non-string keys, you can use a function like that: (It is not as ugly as your "in-place" expression + it works for any number of dictionaries)
from itertools import chain # ← credits go to Niklas B.
def updated(*dicts):
return dict(chain(*map(dict.items, dicts)))
updated({42: 'the answer'}, {1337: 'elite'}) # {42: 'the answer', 1337: 'elite'}
Otherwise Sven’s suggestion is just fine.
Edit: If you are using Python 2.7 or later, you can also use a dictionary comprehension, as Sven suggested in the comments:
def updated(*dicts):
return {k: v for d in dicts for k, v in d.items()}
I don't really see what's wrong in using two lines, like you do:
new_bar = bar.copy()
new_bar.update(extra)
It's clean and readable.
>>> d = {1:2, 3:4}
>>> e = {3:9, 5:25}
>>> f = d.copy()
>>> f.update(e)
>>> d
{1: 2, 3: 4}
>>> f
{1: 2, 3: 9, 5: 25}
>>> e
{3: 9, 5: 25}
In three words: Zen of Python.
To be more clear: My point is that I wouldn't replace those two lines with an updated() function that's not coming from the standard library.
If I was to stumble in a line of code like:
new_bar = updated(bar, extra)
I'd have to track that function down to see what it does. I couldn't trust that it doesn't something strange.
The OP also compared that with sorted(), but sorted() has it's reason to exist, it acts on everything that's iterable and does that with the amazing timsort. Instead what should be the behaviour of an hypothetical updated()? Should that maybe be a dict class method? It's really not clear IMHO.
Said so one could choose the OP two lines, or Sven's solution, or a dict comprehension/generator-expression, I think it's really just a matter of taste.
How do I delete an item from a dictionary in Python?
Without modifying the original dictionary, how do I obtain another dict with the item removed?
See also How can I remove a key from a Python dictionary? for the specific issue of removing an item (by key) that may not already be present.
The del statement removes an element:
del d[key]
Note that this mutates the existing dictionary, so the contents of the dictionary changes for anybody else who has a reference to the same instance. To return a new dictionary, make a copy of the dictionary:
def removekey(d, key):
r = dict(d)
del r[key]
return r
The dict() constructor makes a shallow copy. To make a deep copy, see the copy module.
Note that making a copy for every dict del/assignment/etc. means you're going from constant time to linear time, and also using linear space. For small dicts, this is not a problem. But if you're planning to make lots of copies of large dicts, you probably want a different data structure, like a HAMT (as described in this answer).
pop mutates the dictionary.
>>> lol = {"hello": "gdbye"}
>>> lol.pop("hello")
'gdbye'
>>> lol
{}
If you want to keep the original you could just copy it.
I think your solution is best way to do it. But if you want another solution, you can create a new dictionary with using the keys from old dictionary without including your specified key, like this:
>>> a
{0: 'zero', 1: 'one', 2: 'two', 3: 'three'}
>>> {i:a[i] for i in a if i!=0}
{1: 'one', 2: 'two', 3: 'three'}
There're a lot of nice answers, but I want to emphasize one thing.
You can use both dict.pop() method and a more generic del statement to remove items from a dictionary. They both mutate the original dictionary, so you need to make a copy (see details below).
And both of them will raise a KeyError if the key you're providing to them is not present in the dictionary:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
and
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
You have to take care of this:
by capturing the exception:
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
del d[key_to_remove]
except KeyError as ex:
print("No such key: '%s'" % ex.message)
and
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
d.pop(key_to_remove)
except KeyError as ex:
print("No such key: '%s'" % ex.message)
by performing a check:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
and
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
but with pop() there's also a much more concise way - provide the default return value:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
Unless you use pop() to get the value of a key being removed you may provide anything, not necessary None.
Though it might be that using del with in check is slightly faster due to pop() being a function with its own complications causing overhead. Usually it's not the case, so pop() with default value is good enough.
As for the main question, you'll have to make a copy of your dictionary, to save the original dictionary and have a new one without the key being removed.
Some other people here suggest making a full (deep) copy with copy.deepcopy(), which might be an overkill, a "normal" (shallow) copy, using copy.copy() or dict.copy(), might be enough. The dictionary keeps a reference to the object as a value for a key. So when you remove a key from a dictionary this reference is removed, not the object being referenced. The object itself may be removed later automatically by the garbage collector, if there're no other references for it in the memory. Making a deep copy requires more calculations compared to shallow copy, so it decreases code performance by making the copy, wasting memory and providing more work to the GC, sometimes shallow copy is enough.
However, if you have mutable objects as dictionary values and plan to modify them later in the returned dictionary without the key, you have to make a deep copy.
With shallow copy:
def get_dict_wo_key(dictionary, key):
"""Returns a **shallow** copy of the dictionary without a key."""
_dict = dictionary.copy()
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
With deep copy:
from copy import deepcopy
def get_dict_wo_key(dictionary, key):
"""Returns a **deep** copy of the dictionary without a key."""
_dict = deepcopy(dictionary)
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
The del statement is what you're looking for. If you have a dictionary named foo with a key called 'bar', you can delete 'bar' from foo like this:
del foo['bar']
Note that this permanently modifies the dictionary being operated on. If you want to keep the original dictionary, you'll have to create a copy beforehand:
>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}
The dict call makes a shallow copy. If you want a deep copy, use copy.deepcopy.
Here's a method you can copy & paste, for your convenience:
def minus_key(key, dictionary):
shallow_copy = dict(dictionary)
del shallow_copy[key]
return shallow_copy
… how can I delete an item from a dictionary to return a copy (i.e., not modifying the original)?
A dict is the wrong data structure to use for this.
Sure, copying the dict and popping from the copy works, and so does building a new dict with a comprehension, but all that copying takes time—you've replaced a constant-time operation with a linear-time one. And all those copies alive at once take space—linear space per copy.
Other data structures, like hash array mapped tries, are designed for exactly this kind of use case: adding or removing an element returns a copy in logarithmic time, sharing most of its storage with the original.1
Of course there are some downsides. Performance is logarithmic rather than constant (although with a large base, usually 32-128). And, while you can make the non-mutating API identical to dict, the "mutating" API is obviously different. And, most of all, there's no HAMT batteries included with Python.2
The pyrsistent library is a pretty solid implementation of HAMT-based dict-replacements (and various other types) for Python. It even has a nifty evolver API for porting existing mutating code to persistent code as smoothly as possible. But if you want to be explicit about returning copies rather than mutating, you just use it like this:
>>> from pyrsistent import m
>>> d1 = m(a=1, b=2)
>>> d2 = d1.set('c', 3)
>>> d3 = d1.remove('a')
>>> d1
pmap({'a': 1, 'b': 2})
>>> d2
pmap({'c': 3, 'a': 1, 'b': 2})
>>> d3
pmap({'b': 2})
That d3 = d1.remove('a') is exactly what the question is asking for.
If you've got mutable data structures like dict and list embedded in the pmap, you'll still have aliasing issues—you can only fix that by going immutable all the way down, embedding pmaps and pvectors.
1. HAMTs have also become popular in languages like Scala, Clojure, Haskell because they play very nicely with lock-free programming and software transactional memory, but neither of those is very relevant in Python.
2. In fact, there is an HAMT in the stdlib, used in the implementation of contextvars. The earlier withdrawn PEP explains why. But this is a hidden implementation detail of the library, not a public collection type.
d = {1: 2, '2': 3, 5: 7}
del d[5]
print 'd = ', d
Result: d = {1: 2, '2': 3}
Using del you can remove a dict value passing the key of that value
Link:
del method
del dictionary['key_to_del']
Simply call del d['key'].
However, in production, it is always a good practice to check if 'key' exists in d.
if 'key' in d:
del d['key']
No, there is no other way than
def dictMinus(dct, val):
copy = dct.copy()
del copy[val]
return copy
However, often creating copies of only slightly altered dictionaries is probably not a good idea because it will result in comparatively large memory demands. It is usually better to log the old dictionary(if even necessary) and then modify it.
# mutate/remove with a default
ret_val = body.pop('key', 5)
# no mutation with a default
ret_val = body.get('key', 5)
Here a top level design approach:
def eraseElement(d,k):
if isinstance(d, dict):
if k in d:
d.pop(k)
print(d)
else:
print("Cannot find matching key")
else:
print("Not able to delete")
exp = {'A':34, 'B':55, 'C':87}
eraseElement(exp, 'C')
I'm passing the dictionary and the key I want into my function, validates if it's a dictionary and if the key is okay, and if both exist, removes the value from the dictionary and prints out the left-overs.
Output: {'B': 55, 'A': 34}
Hope that helps!
>>> def delete_key(dict, key):
... del dict[key]
... return dict
...
>>> test_dict = {'one': 1, 'two' : 2}
>>> print delete_key(test_dict, 'two')
{'one': 1}
>>>
this doesn't do any error handling, it assumes the key is in the dict, you might want to check that first and raise if its not
Below code snippet will help you definitely, I have added comments in each line which will help you in understanding the code.
def execute():
dic = {'a':1,'b':2}
dic2 = remove_key_from_dict(dic, 'b')
print(dict2) # {'a': 1}
print(dict) # {'a':1,'b':2}
def remove_key_from_dict(dictionary_to_use, key_to_delete):
copy_of_dict = dict(dictionary_to_use) # creating clone/copy of the dictionary
if key_to_delete in copy_of_dict : # checking given key is present in the dictionary
del copy_of_dict [key_to_delete] # deleting the key from the dictionary
return copy_of_dict # returning the final dictionary
or you can also use dict.pop()
d = {"a": 1, "b": 2}
res = d.pop("c") # No `KeyError` here
print (res) # this line will not execute
or the better approach is
res = d.pop("c", "key not found")
print (res) # key not found
print (d) # {"a": 1, "b": 2}
res = d.pop("b", "key not found")
print (res) # 2
print (d) # {"a": 1}
Solution 1: with deleting
info = {'country': 'Iran'}
country = info.pop('country') if 'country' in info else None
Solution 2: without deleting
info = {'country': 'Iran'}
country = info.get('country') or None
Here's another variation using list comprehension:
original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.iteritems() if v)
# result should be {'b': 'Some'}
The approach is based on an answer from this post:
Efficient way to remove keys with empty strings from a dict
For Python 3 this is
original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.items() if v)
print(d)
species = {'HI': {'1': (1215.671, 0.41600000000000004),
'10': (919.351, 0.0012),
'1025': (1025.722, 0.0791),
'11': (918.129, 0.0009199999999999999),
'12': (917.181, 0.000723),
'1215': (1215.671, 0.41600000000000004),
'13': (916.429, 0.0005769999999999999),
'14': (915.824, 0.000468),
'15': (915.329, 0.00038500000000000003),
'CII': {'1036': (1036.3367, 0.11900000000000001), '1334': (1334.532, 0.129)}}
The following code will make a copy of dict species and delete items which are not in trans_HI
trans_HI=['1025','1215']
for transition in species['HI'].copy().keys():
if transition not in trans_HI:
species['HI'].pop(transition)
In Python 3, 'dict' object has no attribute 'remove'.
But with immutables package, can perform mutations that allow to apply changes to the Map object and create new (derived) Maps:
import immutables
map = immutables.Map(a=1, b=2)
map1 = map.delete('b')
print(map, map1)
# will print:
# <immutables.Map({'b': 2, 'a': 1})>
# <immutables.Map({'a': 1})>
can try my method. In one line.
yourList = [{'key':'key1','version':'1'},{'key':'key2','version':'2'},{'key':'key3','version':'3'}]
resultList = [{'key':dic['key']} for dic in yourList if 'key' in dic]
print(resultList)