Contents
- JavaScript variables
- How to Name JavaScript Variables
- Var, Let and Const Variables
- Scope
- redeclaring Variables
- lifting variables
- Conclusion
Variables are an integral part of almost all programming languages ​​and are usually one of the first things you learn when you start programming. Variables can be used to store data in a program, such as strings, numbers, JSON objects, or Boolean values.
In JavaScript, there are three types of variables:. var
, let
and const
. Each of these variables has different rules for how they should be used and has different characteristics.
In this tutorial, we will explore the basics of variables in JavaScript. We will discuss how to name a JavaScript variable, when you need to use the var,
let,
and const
variables and explore how to raise and the variables impact dell. " field.
JavaScript variables
Variables are used to store data values. For example, a variable can be used to store a user’s email address or name. In JavaScript, a variable can contain any type of data, such as a string, a true or false Boolean, an object or a number.
Before the ES6 specification was released, there was a way to declare a JavaScript variable: var. var
keyword can be used to declare a variable accessible in a program and can be changed.
Here is an example of a variable declared using var
in JavaScript:
Our variable can be divided into a few components:
var
is used to declare our variablefull_name
is the name of our variable=
tells our program that we want to assign a value to our variable (we call thisoperator assignment
)Alexander Smith
is the value of our variable will remember
Now that we have demonstrated the creation of a JavaScript variable, we can the use in our code. Here is an example of a JavaScript program that uses our variable:
Our code returns:
To declare a variable which has no value, you can use the code var variableName
, but without assignment. Here is an example of a variable declared without value:
So if we want to assign a value to our variable we can use this code:
optional, we can add var
at the start of our task, like this:
Now if we print ourExampleVariable
the console, we get the following response: Example
Our variable can store any type of data, as we discussed earlier. Here is an example of some variables that have been assigned different data types:
How to Name JavaScript Variables
Every programming language has its own rules for how to name variables, and JavaScript is no different. Here are the main rules to consider when naming variables in JavaScript:
, JavaScript also uses case sensitive to declare variable names . This refers to writing the first word of a variable in lowercase, then capitalizing each future word in the variable. Here is an example of a variable declared in camel case:
If we have only one word in our variable, each letter must be lowercase.
Also, if you declare a variable using const
, each letter must be in upper case.
While this is a lot of information to learn, over time you will naturally be able to figure out what your variables should be named. All you have to do is practice!
Var, Let and Const Variables
There are three different keywords for declaring a JavaScript variable. They are: var
, let
and const
Here is a table that breaks down the differences between these three types. variables:
< / tbody>Word | variable scope | Reassign? | redeclare? | Raise? |
var | Function | Yes | Yes | Yes |
const | Block | Yes | No | No |
quit | Block | No | No | No |
The following are general rules for using these types of variables:
- Use const , whenever possible, unless you need to replace or increase a variable .
- Use let if you are working with loop .
- Use only var if:
- You are working on previous code ,
- You need a variable that you can re-claim or
- you need a variable that is accessible anywhere in the program (globally) .
os.remove()
removes a file.os.rmdir()
removes an empty directory.shutil.rmtree()
deletes a directory and all its contents.pathlib.Path.unlink()
removes a file or symbolic link.pathlib.Path.rmdir()
removes an empty directory.In Python 3.9.0 or greater (released 17 October 2020): PEP-584, discussed here, was implemented and provides the simplest method:
z = x | y # NOTE: 3.9+ ONLY
In Python 3.5 or greater:
z = {**x, **y}
In Python 2, (or 3.4 or lower) write a function:
def merge_two_dicts(x, y): z = x.copy() # start with keys and values of x z.update(y) # modifies z with keys and values of y return z
and now:
z = merge_two_dicts(x, y)
- My explanation of Python"s dictionary implementation, updated for 3.6.
- Answer on how to add new keys to a dictionary
- Mapping two lists into a dictionary
- The official Python docs on dictionaries
- The Dictionary Even Mightier - talk by Brandon Rhodes at Pycon 2017
- Modern Python Dictionaries, A Confluence of Great Ideas - talk by Raymond Hettinger at Pycon 2017
- Parse a string to receive day, month and year as three integer variables or a 3-item tuple consisting of that variable.
- Instantiate
Date
by passing those values to the initialization call. - We"ve implemented date string parsing in one place and it"s reusable now.
- Encapsulation works fine here (if you think that you could implement string parsing as a single function elsewhere, this solution fits the OOP paradigm far better).
cls
is an object that holds the class itself, not an instance of the class. It"s pretty cool because if we inherit ourDate
class, all children will havefrom_string
defined also.In Python 3.9.0 or greater (released 17 October 2020): PEP-584, discussed here, was implemented and provides the simplest method:
z = x | y # NOTE: 3.9+ ONLY
In Python 3.5 or greater:
z = {**x, **y}
In Python 2, (or 3.4 or lower) write a function:
def merge_two_dicts(x, y): z = x.copy() # start with keys and values of x z.update(y) # modifies z with keys and values of y return z
and now:
z = merge_two_dicts(x, y)
- My explanation of Python"s dictionary implementation, updated for 3.6.
- Answer on how to add new keys to a dictionary
- Mapping two lists into a dictionary
- The official Python docs on dictionaries
- The Dictionary Even Mightier - talk by Brandon Rhodes at Pycon 2017
- Modern Python Dictionaries, A Confluence of Great Ideas - talk by Raymond Hettinger at Pycon 2017
If you are interested in learning more about these types of variables, check out our tutorial on how to use JavaScript
let
variables hereThis table contains a lot of information, so we’ll analyze each of the main differences between these types of variables: .
field
,reassignment
,rideclaration
andhissage
.Scope
Scope is used to designate where a variable is accessible within a program. There are two application fields in JavaScript:
global scope
, which is where a variable is declared outside of a block of code; andlocal goal
, where a variable is declared in a code blockHere is an example of a global variable in JavaScript:
This variable is available throughout our program. So if we want to access our
name
variable later in functions, we can do that.Local variables are declared in a given code block. To declare a local variable, you must use
let
andconst
, which are assigned a block field. Here is an example oflet
used in a program:Our code returns the elements include:
As you can see, since
day
is the same asMonday
, our program runs the contents of ourif
declaration. Then our program changes the value of theflavor
variableChoc-Chip
and prints the first message we saw above.But after
if
the declaration was executed, the value offlavor
returns toVanilla
, which was declared globally at the start of our program. Then, in the last line of code, our program prints a message asking us to have a scoop of vanilla ice cream, becauseflavor
has been assigned the valueVanilla
in the world.redeclaring Variables
In JavaScript, only
var
variables can be redeclared. This means that you can create a new variable with the same name and keep its value, or assign a different value to the variable.Here is an example of a program that declares a variable called
RADIOSHOW
, redeclares the variable:Our code returns:
KACL
. In our code, we declaredRADIOSHOW
twice. Without useful in the previous example, if we had an older program, we might want to redeclare a variable. Therefore, if we expect to want to redeclare a variable, we should usevar
to declare it.lifting variables
In JavaScript, a variable can be declared after it has been used, meaning that a variable can be used before it has been declared.
Let’s use an example to illustrate how the lifting works let’s say we declare a variable called
students
which contains a list of student names, but we declare this variable after asking our program to print it.Our program returns:
But if we try to declare our variable without the
var
keyword, our r program would result as follows:This shows the elevator in action. Variables can be declared after being referenced using
var
keyword. Simply put, our program interpreted the previous example as follows:Contrary variables declared using
var
,let
andconst
cannot be hoisted. Here is an example of a program that useslet
to declare a variable:When our code is executed, the following result will be returned:
Rand Graham
. Thelet name = Mark Swinton;
declaration is wrapped in our function, which means it has local scope. Since we are using thelet
keyword, our variable is not hoisted.In summary, variables using
var
are subject to throwing, which stores variable declarations in memory. This can cause problems if you set and assign variables in the wrong order.let
andconst
variables are not subject to this function however, which means an error will be returned if you try to declare a variable longer than ’once or refer to a variable that has not yet been declared in the domain concerned.Conclusion
Variables are an important Through programming and are used to store data values. In this article, we have discussed the basics of JavaScript variables and listed the rules to follow when naming variables
We have also discussed the three main types of variables in JavaScript -.
var
,let
andconst
- and explored how they can be used. Finally, we discussed the role of scoping, overriding variables and lifting JavaScript variables.You now have the knowledge to declare and use variables like a JavaScript expert!
Javascript Variable: StackOverflow Questions
How can I make a time delay in Python?
I would like to know how to put a time delay in a Python script.
Answer #1:
import time time.sleep(5) # Delays for 5 seconds. You can also use a float value.
Here is another example where something is run approximately once a minute:
import time while True: print("This prints once a minute.") time.sleep(60) # Delay for 1 minute (60 seconds).
Answer #2:
You can use the
sleep()
function in thetime
module. It can take a float argument for sub-second resolution.from time import sleep sleep(0.1) # Time in seconds
Answer #3:
How can I make a time delay in Python?
In a single thread I suggest the sleep function:
>>> from time import sleep >>> sleep(4)
This function actually suspends the processing of the thread in which it is called by the operating system, allowing other threads and processes to execute while it sleeps.
Use it for that purpose, or simply to delay a function from executing. For example:
>>> def party_time(): ... print("hooray!") ... >>> sleep(3); party_time() hooray!
"hooray!" is printed 3 seconds after I hit Enter.
Example using
sleep
with multiple threads and processesAgain,
sleep
suspends your thread - it uses next to zero processing power.To demonstrate, create a script like this (I first attempted this in an interactive Python 3.5 shell, but sub-processes can"t find the
party_later
function for some reason):from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed from time import sleep, time def party_later(kind="", n=""): sleep(3) return kind + n + " party time!: " + __name__ def main(): with ProcessPoolExecutor() as proc_executor: with ThreadPoolExecutor() as thread_executor: start_time = time() proc_future1 = proc_executor.submit(party_later, kind="proc", n="1") proc_future2 = proc_executor.submit(party_later, kind="proc", n="2") thread_future1 = thread_executor.submit(party_later, kind="thread", n="1") thread_future2 = thread_executor.submit(party_later, kind="thread", n="2") for f in as_completed([ proc_future1, proc_future2, thread_future1, thread_future2,]): print(f.result()) end_time = time() print("total time to execute four 3-sec functions:", end_time - start_time) if __name__ == "__main__": main()
Example output from this script:
thread1 party time!: __main__ thread2 party time!: __main__ proc1 party time!: __mp_main__ proc2 party time!: __mp_main__ total time to execute four 3-sec functions: 3.4519670009613037
Multithreading
You can trigger a function to be called at a later time in a separate thread with the
Timer
threading object:>>> from threading import Timer >>> t = Timer(3, party_time, args=None, kwargs=None) >>> t.start() >>> >>> hooray! >>>
The blank line illustrates that the function printed to my standard output, and I had to hit Enter to ensure I was on a prompt.
The upside of this method is that while the
Timer
thread was waiting, I was able to do other things, in this case, hitting Enter one time - before the function executed (see the first empty prompt).There isn"t a respective object in the multiprocessing library. You can create one, but it probably doesn"t exist for a reason. A sub-thread makes a lot more sense for a simple timer than a whole new subprocess.
Answer #4:
Delays can be also implemented by using the following methods.
The first method:
import time time.sleep(5) # Delay for 5 seconds.
The second method to delay would be using the implicit wait method:
driver.implicitly_wait(5)
The third method is more useful when you have to wait until a particular action is completed or until an element is found:
self.wait.until(EC.presence_of_element_located((By.ID, "UserName"))
How to delete a file or folder in Python?
How do I delete a file or folder in Python?
Answer #1:
Path
objects from the Python 3.4+pathlib
module also expose these instance methods:Javascript Variable: StackOverflow Questions
How do I merge two dictionaries in a single expression (taking union of dictionaries)?
Question by Carl Meyer
I have two Python dictionaries, and I want to write a single expression that returns these two dictionaries, merged (i.e. taking the union). The
update()
method would be what I need, if it returned its result instead of modifying a dictionary in-place.>>> x = {"a": 1, "b": 2} >>> y = {"b": 10, "c": 11} >>> z = x.update(y) >>> print(z) None >>> x {"a": 1, "b": 10, "c": 11}
How can I get that final merged dictionary in
z
, notx
?(To be extra-clear, the last-one-wins conflict-handling of
dict.update()
is what I"m looking for as well.)Answer #1:
How can I merge two Python dictionaries in a single expression?
For dictionaries
x
andy
,z
becomes a shallowly-merged dictionary with values fromy
replacing those fromx
.Explanation
Say you have two dictionaries and you want to merge them into a new dictionary without altering the original dictionaries:
x = {"a": 1, "b": 2} y = {"b": 3, "c": 4}
The desired result is to get a new dictionary (
z
) with the values merged, and the second dictionary"s values overwriting those from the first.>>> z {"a": 1, "b": 3, "c": 4}
A new syntax for this, proposed in PEP 448 and available as of Python 3.5, is
z = {**x, **y}
And it is indeed a single expression.
Note that we can merge in with literal notation as well:
z = {**x, "foo": 1, "bar": 2, **y}
and now:
>>> z {"a": 1, "b": 3, "foo": 1, "bar": 2, "c": 4}
It is now showing as implemented in the release schedule for 3.5, PEP 478, and it has now made its way into the What"s New in Python 3.5 document.
However, since many organizations are still on Python 2, you may wish to do this in a backward-compatible way. The classically Pythonic way, available in Python 2 and Python 3.0-3.4, is to do this as a two-step process:
z = x.copy() z.update(y) # which returns None since it mutates z
In both approaches,
y
will come second and its values will replacex
"s values, thusb
will point to3
in our final result.Not yet on Python 3.5, but want a single expression
If you are not yet on Python 3.5 or need to write backward-compatible code, and you want this in a single expression, the most performant while the correct approach is to put it in a function:
def merge_two_dicts(x, y): """Given two dictionaries, merge them into a new dict as a shallow copy.""" z = x.copy() z.update(y) return z
and then you have a single expression:
z = merge_two_dicts(x, y)
You can also make a function to merge an arbitrary number of dictionaries, from zero to a very large number:
def merge_dicts(*dict_args): """ Given any number of dictionaries, shallow copy and merge into a new dict, precedence goes to key-value pairs in latter dictionaries. """ result = {} for dictionary in dict_args: result.update(dictionary) return result
This function will work in Python 2 and 3 for all dictionaries. e.g. given dictionaries
a
tog
:z = merge_dicts(a, b, c, d, e, f, g)
and key-value pairs in
g
will take precedence over dictionariesa
tof
, and so on.Critiques of Other Answers
Don"t use what you see in the formerly accepted answer:
z = dict(x.items() + y.items())
In Python 2, you create two lists in memory for each dict, create a third list in memory with length equal to the length of the first two put together, and then discard all three lists to create the dict. In Python 3, this will fail because you"re adding two
dict_items
objects together, not two lists ->>> c = dict(a.items() + b.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: "dict_items" and "dict_items"
and you would have to explicitly create them as lists, e.g.
z = dict(list(x.items()) + list(y.items()))
. This is a waste of resources and computation power.Similarly, taking the union of
items()
in Python 3 (viewitems()
in Python 2.7) will also fail when values are unhashable objects (like lists, for example). Even if your values are hashable, since sets are semantically unordered, the behavior is undefined in regards to precedence. So don"t do this:>>> c = dict(a.items() | b.items())
This example demonstrates what happens when values are unhashable:
>>> x = {"a": []} >>> y = {"b": []} >>> dict(x.items() | y.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: "list"
Here"s an example where
y
should have precedence, but instead the value fromx
is retained due to the arbitrary order of sets:>>> x = {"a": 2} >>> y = {"a": 1} >>> dict(x.items() | y.items()) {"a": 2}
Another hack you should not use:
z = dict(x, **y)
This uses the
dict
constructor and is very fast and memory-efficient (even slightly more so than our two-step process) but unless you know precisely what is happening here (that is, the second dict is being passed as keyword arguments to the dict constructor), it"s difficult to read, it"s not the intended usage, and so it is not Pythonic.Here"s an example of the usage being remediated in django.
Dictionaries are intended to take hashable keys (e.g.
frozenset
s or tuples), but this method fails in Python 3 when keys are not strings.>>> c = dict(a, **b) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: keyword arguments must be strings
From the mailing list, Guido van Rossum, the creator of the language, wrote:
I am fine with declaring dict({}, **{1:3}) illegal, since after all it is abuse of the ** mechanism.
and
Apparently dict(x, **y) is going around as "cool hack" for "call x.update(y) and return x". Personally, I find it more despicable than cool.
It is my understanding (as well as the understanding of the creator of the language) that the intended usage for
dict(**y)
is for creating dictionaries for readability purposes, e.g.:dict(a=1, b=10, c=11)
instead of
{"a": 1, "b": 10, "c": 11}
Response to comments
Despite what Guido says,
dict(x, **y)
is in line with the dict specification, which btw. works for both Python 2 and 3. The fact that this only works for string keys is a direct consequence of how keyword parameters work and not a short-coming of dict. Nor is using the ** operator in this place an abuse of the mechanism, in fact, ** was designed precisely to pass dictionaries as keywords.Again, it doesn"t work for 3 when keys are not strings. The implicit calling contract is that namespaces take ordinary dictionaries, while users must only pass keyword arguments that are strings. All other callables enforced it.
dict
broke this consistency in Python 2:>>> foo(**{("a", "b"): None}) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() keywords must be strings >>> dict(**{("a", "b"): None}) {("a", "b"): None}
This inconsistency was bad given other implementations of Python (PyPy, Jython, IronPython). Thus it was fixed in Python 3, as this usage could be a breaking change.
I submit to you that it is malicious incompetence to intentionally write code that only works in one version of a language or that only works given certain arbitrary constraints.
More comments:
dict(x.items() + y.items())
is still the most readable solution for Python 2. Readability counts.My response:
merge_two_dicts(x, y)
actually seems much clearer to me, if we"re actually concerned about readability. And it is not forward compatible, as Python 2 is increasingly deprecated.{**x, **y}
does not seem to handle nested dictionaries. the contents of nested keys are simply overwritten, not merged [...] I ended up being burnt by these answers that do not merge recursively and I was surprised no one mentioned it. In my interpretation of the word "merging" these answers describe "updating one dict with another", and not merging.Yes. I must refer you back to the question, which is asking for a shallow merge of two dictionaries, with the first"s values being overwritten by the second"s - in a single expression.
Assuming two dictionaries of dictionaries, one might recursively merge them in a single function, but you should be careful not to modify the dictionaries from either source, and the surest way to avoid that is to make a copy when assigning values. As keys must be hashable and are usually therefore immutable, it is pointless to copy them:
from copy import deepcopy def dict_of_dicts_merge(x, y): z = {} overlapping_keys = x.keys() & y.keys() for key in overlapping_keys: z[key] = dict_of_dicts_merge(x[key], y[key]) for key in x.keys() - overlapping_keys: z[key] = deepcopy(x[key]) for key in y.keys() - overlapping_keys: z[key] = deepcopy(y[key]) return z
Usage:
>>> x = {"a":{1:{}}, "b": {2:{}}} >>> y = {"b":{10:{}}, "c": {11:{}}} >>> dict_of_dicts_merge(x, y) {"b": {2: {}, 10: {}}, "a": {1: {}}, "c": {11: {}}}
Coming up with contingencies for other value types is far beyond the scope of this question, so I will point you at my answer to the canonical question on a "Dictionaries of dictionaries merge".
Less Performant But Correct Ad-hocs
These approaches are less performant, but they will provide correct behavior. They will be much less performant than
copy
andupdate
or the new unpacking because they iterate through each key-value pair at a higher level of abstraction, but they do respect the order of precedence (latter dictionaries have precedence)You can also chain the dictionaries manually inside a dict comprehension:
{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7
or in Python 2.6 (and perhaps as early as 2.4 when generator expressions were introduced):
dict((k, v) for d in dicts for k, v in d.items()) # iteritems in Python 2
itertools.chain
will chain the iterators over the key-value pairs in the correct order:from itertools import chain z = dict(chain(x.items(), y.items())) # iteritems in Python 2
Performance Analysis
I"m only going to do the performance analysis of the usages known to behave correctly. (Self-contained so you can copy and paste yourself.)
from timeit import repeat from itertools import chain x = dict.fromkeys("abcdefg") y = dict.fromkeys("efghijk") def merge_two_dicts(x, y): z = x.copy() z.update(y) return z min(repeat(lambda: {**x, **y})) min(repeat(lambda: merge_two_dicts(x, y))) min(repeat(lambda: {k: v for d in (x, y) for k, v in d.items()})) min(repeat(lambda: dict(chain(x.items(), y.items())))) min(repeat(lambda: dict(item for d in (x, y) for item in d.items())))
In Python 3.8.1, NixOS:
>>> min(repeat(lambda: {**x, **y})) 1.0804965235292912 >>> min(repeat(lambda: merge_two_dicts(x, y))) 1.636518670246005 >>> min(repeat(lambda: {k: v for d in (x, y) for k, v in d.items()})) 3.1779992282390594 >>> min(repeat(lambda: dict(chain(x.items(), y.items())))) 2.740647904574871 >>> min(repeat(lambda: dict(item for d in (x, y) for item in d.items()))) 4.266070580109954
$ uname -a Linux nixos 4.19.113 #1-NixOS SMP Wed Mar 25 07:06:15 UTC 2020 x86_64 GNU/Linux
Resources on Dictionaries
Answer #2:
In your case, what you can do is:
z = dict(list(x.items()) + list(y.items()))
This will, as you want it, put the final dict in
z
, and make the value for keyb
be properly overridden by the second (y
) dict"s value:>>> x = {"a":1, "b": 2} >>> y = {"b":10, "c": 11} >>> z = dict(list(x.items()) + list(y.items())) >>> z {"a": 1, "c": 11, "b": 10}
If you use Python 2, you can even remove the
list()
calls. To create z:>>> z = dict(x.items() + y.items()) >>> z {"a": 1, "c": 11, "b": 10}
If you use Python version 3.9.0a4 or greater, then you can directly use:
x = {"a":1, "b": 2} y = {"b":10, "c": 11} z = x | y print(z)
{"a": 1, "c": 11, "b": 10}
Answer #3:
An alternative:
z = x.copy() z.update(y)
Answer #4:
Another, more concise, option:
z = dict(x, **y)
Note: this has become a popular answer, but it is important to point out that if
y
has any non-string keys, the fact that this works at all is an abuse of a CPython implementation detail, and it does not work in Python 3, or in PyPy, IronPython, or Jython. Also, Guido is not a fan. So I can"t recommend this technique for forward-compatible or cross-implementation portable code, which really means it should be avoided entirely.Answer #5:
This probably won"t be a popular answer, but you almost certainly do not want to do this. If you want a copy that"s a merge, then use copy (or deepcopy, depending on what you want) and then update. The two lines of code are much more readable - more Pythonic - than the single line creation with .items() + .items(). Explicit is better than implicit.
In addition, when you use .items() (pre Python 3.0), you"re creating a new list that contains the items from the dict. If your dictionaries are large, then that is quite a lot of overhead (two large lists that will be thrown away as soon as the merged dict is created). update() can work more efficiently, because it can run through the second dict item-by-item.
In terms of time:
>>> timeit.Timer("dict(x, **y)", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 15.52571702003479 >>> timeit.Timer("temp = x.copy() temp.update(y)", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 15.694622993469238 >>> timeit.Timer("dict(x.items() + y.items())", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 41.484580039978027
IMO the tiny slowdown between the first two is worth it for the readability. In addition, keyword arguments for dictionary creation was only added in Python 2.3, whereas copy() and update() will work in older versions.
Javascript Variable: StackOverflow Questions
JSON datetime between Python and JavaScript
Question by kevin
I want to send a datetime.datetime object in serialized form from Python using JSON and de-serialize in JavaScript using JSON. What is the best way to do this?
Answer #1:
You can add the "default" parameter to json.dumps to handle this:
date_handler = lambda obj: ( obj.isoformat() if isinstance(obj, (datetime.datetime, datetime.date)) else None ) json.dumps(datetime.datetime.now(), default=date_handler) ""2010-04-20T20:08:21.634121""
Which is ISO 8601 format.
A more comprehensive default handler function:
def handler(obj): if hasattr(obj, "isoformat"): return obj.isoformat() elif isinstance(obj, ...): return ... else: raise TypeError, "Object of type %s with value of %s is not JSON serializable" % (type(obj), repr(obj))
Update: Added output of type as well as value.
Update: Also handle dateJavascript equivalent of Python"s zip function
Is there a javascript equivalent of Python"s zip function? That is, given multiple arrays of equal lengths create an array of pairs.
For instance, if I have three arrays that look like this:
var array1 = [1, 2, 3]; var array2 = ["a","b","c"]; var array3 = [4, 5, 6];
The output array should be:
var output array:[[1,"a",4], [2,"b",5], [3,"c",6]]
Answer #1:
2016 update:
Here"s a snazzier Ecmascript 6 version:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
Illustration equiv. to Python{
zip(*args)
}:> zip([["row0col0", "row0col1", "row0col2"], ["row1col0", "row1col1", "row1col2"]]); [["row0col0","row1col0"], ["row0col1","row1col1"], ["row0col2","row1col2"]]
(and FizzyTea points out that ES6 has variadic argument syntax, so the following function definition will act like python, but see below for disclaimer... this will not be its own inverse so
zip(zip(x))
will not equalx
; though as Matt Kramer points outzip(...zip(...x))==x
(like in regular pythonzip(*zip(*x))==x
))Alternative definition equiv. to Python{
zip
}:> zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c])) > zip( ["row0col0", "row0col1", "row0col2"] , ["row1col0", "row1col1", "row1col2"] ); // note zip(row0,row1), not zip(matrix) same answer as above
(Do note that the
...
syntax may have performance issues at this time, and possibly in the future, so if you use the second answer with variadic arguments, you may want to perf test it. That said it"s been quite a while since it"s been in the standard.)Make sure to note the addendum if you wish to use this on strings (perhaps there"s a better way to do it now with es6 iterables).
Here"s a oneliner:
function zip(arrays) { return arrays[0].map(function(_,i){ return arrays.map(function(array){return array[i]}) }); } // > zip([[1,2],[11,22],[111,222]]) // [[1,11,111],[2,22,222]]] // If you believe the following is a valid return value: // > zip([]) // [] // then you can special-case it, or just do // return arrays.length==0 ? [] : arrays[0].map(...)
The above assumes that the arrays are of equal size, as they should be. It also assumes you pass in a single list of lists argument, unlike Python"s version where the argument list is variadic. If you want all of these "features", see below. It takes just about 2 extra lines of code.
The following will mimic Python"s
zip
behavior on edge cases where the arrays are not of equal size, silently pretending the longer parts of arrays don"t exist:function zip() { var args = [].slice.call(arguments); var shortest = args.length==0 ? [] : args.reduce(function(a,b){ return a.length<b.length ? a : b }); return shortest.map(function(_,i){ return args.map(function(array){return array[i]}) }); } // > zip([1,2],[11,22],[111,222,333]) // [[1,11,111],[2,22,222]]] // > zip() // []
This will mimic Python"s
itertools.zip_longest
behavior, insertingundefined
where arrays are not defined:function zip() { var args = [].slice.call(arguments); var longest = args.reduce(function(a,b){ return a.length>b.length ? a : b }, []); return longest.map(function(_,i){ return args.map(function(array){return array[i]}) }); } // > zip([1,2],[11,22],[111,222,333]) // [[1,11,111],[2,22,222],[null,null,333]] // > zip() // []
If you use these last two version (variadic aka. multiple-argument versions), then zip is no longer its own inverse. To mimic the
zip(*[...])
idiom from Python, you will need to dozip.apply(this, [...])
when you want to invert the zip function or if you want to similarly have a variable number of lists as input.
addendum:
To make this handle any iterable (e.g. in Python you can use
zip
on strings, ranges, map objects, etc.), you could define the following:function iterView(iterable) { // returns an array equivalent to the iterable }
However if you write
zip
in the following way, even that won"t be necessary:function zip(arrays) { return Array.apply(null,Array(arrays[0].length)).map(function(_,i){ return arrays.map(function(array){return array[i]}) }); }
Demo:
> JSON.stringify( zip(["abcde",[1,2,3,4,5]]) ) [["a",1],["b",2],["c",3],["d",4],["e",5]]
(Or you could use a
range(...)
Python-style function if you"ve written one already. Eventually you will be able to use ECMAScript array comprehensions or generators.)What blocks Ruby, Python to get Javascript V8 speed?
Are there any Ruby / Python features that are blocking implementation of optimizations (e.g. inline caching) V8 engine has?
Python is co-developed by Google guys so it shouldn"t be blocked by software patents.
Or this is rather matter of resources put into the V8 project by Google.
Answer #1:
What blocks Ruby, Python to get Javascript V8 speed?
Nothing.
Well, okay: money. (And time, people, resources, but if you have money, you can buy those.)
V8 has a team of brilliant, highly-specialized, highly-experienced (and thus highly-paid) engineers working on it, that have decades of experience (I"m talking individually – collectively it"s more like centuries) in creating high-performance execution engines for dynamic OO languages. They are basically the same people who also created the Sun HotSpot JVM (among many others).
Lars Bak, the lead developer, has been literally working on VMs for 25 years (and all of those VMs have lead up to V8), which is basically his entire (professional) life. Some of the people writing Ruby VMs aren"t even 25 years old.
Are there any Ruby / Python features that are blocking implementation of optimizations (e.g. inline caching) V8 engine has?
Given that at least IronRuby, JRuby, MagLev, MacRuby and Rubinius have either monomorphic (IronRuby) or polymorphic inline caching, the answer is obviously no.
Modern Ruby implementations already do a great deal of optimizations. For example, for certain operations, Rubinius"s
Hash
class is faster than YARV"s. Now, this doesn"t sound terribly exciting until you realize that Rubinius"sHash
class is implemented in 100% pure Ruby, while YARV"s is implemented in 100% hand-optimized C.So, at least in some cases, Rubinius can generate better code than GCC!
Or this is rather matter of resources put into the V8 project by Google.
Yes. Not just Google. The lineage of V8"s source code is 25 years old now. The people who are working on V8 also created the Self VM (to this day one of the fastest dynamic OO language execution engines ever created), the Animorphic Smalltalk VM (to this day one of the fastest Smalltalk execution engines ever created), the HotSpot JVM (the fastest JVM ever created, probably the fastest VM period) and OOVM (one of the most efficient Smalltalk VMs ever created).
In fact, Lars Bak, the lead developer of V8, worked on every single one of those, plus a few others.
Django Template Variables and Javascript
When I render a page using the Django template renderer, I can pass in a dictionary variable containing various values to manipulate them in the page using
{{ myVar }}
.Is there a way to access the same variable in Javascript (perhaps using the DOM, I don"t know how Django makes the variables accessible)? I want to be able to lookup details using an AJAX lookup based on the values contained in the variables passed in.
Answer #1:
The
{{variable}}
is substituted directly into the HTML. Do a view source; it isn"t a "variable" or anything like it. It"s just rendered text.Having said that, you can put this kind of substitution into your JavaScript.
<script type="text/javascript"> var a = "{{someDjangoVariable}}"; </script>
This gives you "dynamic" javascript.
Web-scraping JavaScript page with Python
I"m trying to develop a simple web scraper. I want to extract text without the HTML code. In fact, I achieve this goal, but I have seen that in some pages where JavaScript is loaded I didn"t obtain good results.
For example, if some JavaScript code adds some text, I can"t see it, because when I call
response = urllib2.urlopen(request)
I get the original text without the added one (because JavaScript is executed in the client).
So, I"m looking for some ideas to solve this problem.
Answer #1:
EDIT 30/Dec/2017: This answer appears in top results of Google searches, so I decided to update it. The old answer is still at the end.
dryscape isn"t maintained anymore and the library dryscape developers recommend is Python 2 only. I have found using Selenium"s python library with Phantom JS as a web driver fast enough and easy to get the work done.
Once you have installed Phantom JS, make sure the
phantomjs
binary is available in the current path:phantomjs --version # result: 2.1.1
Example
To give an example, I created a sample page with following HTML code. (link):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Javascript scraping test</title> </head> <body> <p id="intro-text">No javascript support</p> <script> document.getElementById("intro-text").innerHTML = "Yay! Supports javascript"; </script> </body> </html>
without javascript it says:
No javascript support
and with javascript:Yay! Supports javascript
Scraping without JS support:
import requests from bs4 import BeautifulSoup response = requests.get(my_url) soup = BeautifulSoup(response.text) soup.find(id="intro-text") # Result: <p id="intro-text">No javascript support</p>
Scraping with JS support:
from selenium import webdriver driver = webdriver.PhantomJS() driver.get(my_url) p_element = driver.find_element_by_id(id_="intro-text") print(p_element.text) # result: "Yay! Supports javascript"
You can also use Python library dryscrape to scrape javascript driven websites.
Scraping with JS support:
import dryscrape from bs4 import BeautifulSoup session = dryscrape.Session() session.visit(my_url) response = session.body() soup = BeautifulSoup(response) soup.find(id="intro-text") # Result: <p id="intro-text">Yay! Supports javascript</p>
Javascript Variable: StackOverflow Questions
Meaning of @classmethod and @staticmethod for beginner?
Question by user1632861
Could someone explain to me the meaning of
@classmethod
and@staticmethod
in python? I need to know the difference and the meaning.As far as I understand,
@classmethod
tells a class that it"s a method which should be inherited into subclasses, or... something. However, what"s the point of that? Why not just define the class method without adding@classmethod
or@staticmethod
or any@
definitions?tl;dr: when should I use them, why should I use them, and how should I use them?
Answer #1:
Though
classmethod
andstaticmethod
are quite similar, there"s a slight difference in usage for both entities:classmethod
must have a reference to a class object as the first parameter, whereasstaticmethod
can have no parameters at all.Example
class Date(object): def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year @classmethod def from_string(cls, date_as_string): day, month, year = map(int, date_as_string.split("-")) date1 = cls(day, month, year) return date1 @staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string.split("-")) return day <= 31 and month <= 12 and year <= 3999 date2 = Date.from_string("11-09-2012") is_date = Date.is_date_valid("11-09-2012")
Explanation
Let"s assume an example of a class, dealing with date information (this will be our boilerplate):
class Date(object): def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year
This class obviously could be used to store information about certain dates (without timezone information; let"s assume all dates are presented in UTC).
Here we have
__init__
, a typical initializer of Python class instances, which receives arguments as a typicalinstancemethod
, having the first non-optional argument (self
) that holds a reference to a newly created instance.Class Method
We have some tasks that can be nicely done using
classmethod
s.Let"s assume that we want to create a lot of
Date
class instances having date information coming from an outer source encoded as a string with format "dd-mm-yyyy". Suppose we have to do this in different places in the source code of our project.So what we must do here is:
This will look like:
day, month, year = map(int, string_date.split("-")) date1 = Date(day, month, year)
For this purpose, C++ can implement such a feature with overloading, but Python lacks this overloading. Instead, we can use
classmethod
. Let"s create another "constructor".@classmethod def from_string(cls, date_as_string): day, month, year = map(int, date_as_string.split("-")) date1 = cls(day, month, year) return date1 date2 = Date.from_string("11-09-2012")
Let"s look more carefully at the above implementation, and review what advantages we have here:
Static method
What about
staticmethod
? It"s pretty similar toclassmethod
but doesn"t take any obligatory parameters (like a class method or instance method does).Let"s look at the next use case.
We have a date string that we want to validate somehow. This task is also logically bound to the
Date
class we"ve used so far, but doesn"t require instantiation of it.Here is where
staticmethod
can be useful. Let"s look at the next piece of code:@staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string.split("-")) return day <= 31 and month <= 12 and year <= 3999 # usage: is_date = Date.is_date_valid("11-09-2012")
So, as we can see from usage of
staticmethod
, we don"t have any access to what the class is---it"s basically just a function, called syntactically like a method, but without access to the object and its internals (fields and another methods), while classmethod does.Answer #2:
Rostyslav Dzinko"s answer is very appropriate. I thought I could highlight one other reason you should choose
@classmethod
over@staticmethod
when you are creating an additional constructor.In the example above, Rostyslav used the
@classmethod
from_string
as a Factory to createDate
objects from otherwise unacceptable parameters. The same can be done with@staticmethod
as is shown in the code below:class Date: def __init__(self, month, day, year): self.month = month self.day = day self.year = year def display(self): return "{0}-{1}-{2}".format(self.month, self.day, self.year) @staticmethod def millenium(month, day): return Date(month, day, 2000) new_year = Date(1, 1, 2013) # Creates a new Date object millenium_new_year = Date.millenium(1, 1) # also creates a Date object. # Proof: new_year.display() # "1-1-2013" millenium_new_year.display() # "1-1-2000" isinstance(new_year, Date) # True isinstance(millenium_new_year, Date) # True
Thus both
new_year
andmillenium_new_year
are instances of theDate
class.But, if you observe closely, the Factory process is hard-coded to create
Date
objects no matter what. What this means is that even if theDate
class is subclassed, the subclasses will still create plainDate
objects (without any properties of the subclass). See that in the example below:class DateTime(Date): def display(self): return "{0}-{1}-{2} - 00:00:00PM".format(self.month, self.day, self.year) datetime1 = DateTime(10, 10, 1990) datetime2 = DateTime.millenium(10, 10) isinstance(datetime1, DateTime) # True isinstance(datetime2, DateTime) # False datetime1.display() # returns "10-10-1990 - 00:00:00PM" datetime2.display() # returns "10-10-2000" because it"s not a DateTime object but a Date object. Check the implementation of the millenium method on the Date class for more details.
datetime2
is not an instance ofDateTime
? WTF? Well, that"s because of the@staticmethod
decorator used.In most cases, this is undesired. If what you want is a Factory method that is aware of the class that called it, then
@classmethod
is what you need.Rewriting
Date.millenium
as (that"s the only part of the above code that changes):@classmethod def millenium(cls, month, day): return cls(month, day, 2000)
ensures that the
class
is not hard-coded but rather learnt.cls
can be any subclass. The resultingobject
will rightly be an instance ofcls
.
Let"s test that out:datetime1 = DateTime(10, 10, 1990) datetime2 = DateTime.millenium(10, 10) isinstance(datetime1, DateTime) # True isinstance(datetime2, DateTime) # True datetime1.display() # "10-10-1990 - 00:00:00PM" datetime2.display() # "10-10-2000 - 00:00:00PM"
The reason is, as you know by now, that
@classmethod
was used instead of@staticmethod
Answer #3:
@classmethod
means: when this method is called, we pass the class as the first argument instead of the instance of that class (as we normally do with methods). This means you can use the class and its properties inside that method rather than a particular instance.@staticmethod
means: when this method is called, we don"t pass an instance of the class to it (as we normally do with methods). This means you can put a function inside a class but you can"t access the instance of that class (this is useful when your method does not use the instance).What is the meaning of single and double underscore before an object name?
Can someone please explain the exact meaning of having single and double leading underscores before an object"s name in Python, and the difference between both?
Also, does that meaning stay the same regardless of whether the object in question is a variable, a function, a method, etc.?
Answer #1:
Single Underscore
Names, in a class, with a leading underscore are simply to indicate to other programmers that the attribute or method is intended to be private. However, nothing special is done with the name itself.
To quote PEP-8:
_single_leading_underscore: weak "internal use" indicator. E.g.
from M import *
does not import objects whose name starts with an underscore.Double Underscore (Name Mangling)
From the Python docs:
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.And a warning from the same page:
Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
Example
>>> class MyClass(): ... def __init__(self): ... self.__superprivate = "Hello" ... self._semiprivate = ", world!" ... >>> mc = MyClass() >>> print mc.__superprivate Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: myClass instance has no attribute "__superprivate" >>> print mc._semiprivate , world! >>> print mc.__dict__ {"_MyClass__superprivate": "Hello", "_semiprivate": ", world!"}
Answer #2:
__foo__
: this is just a convention, a way for the Python system to use names that won"t conflict with user names._foo
: this is just a convention, a way for the programmer to indicate that the variable is private (whatever that means in Python).__foo
: this has real meaning: the interpreter replaces this name with_classname__foo
as a way to ensure that the name will not overlap with a similar name in another class.No other form of underscores have meaning in the Python world.
There"s no difference between class, variable, global, etc in these conventions.
Javascript Variable: StackOverflow Questions
How do I merge two dictionaries in a single expression (taking union of dictionaries)?
Question by Carl Meyer
I have two Python dictionaries, and I want to write a single expression that returns these two dictionaries, merged (i.e. taking the union). The
update()
method would be what I need, if it returned its result instead of modifying a dictionary in-place.>>> x = {"a": 1, "b": 2} >>> y = {"b": 10, "c": 11} >>> z = x.update(y) >>> print(z) None >>> x {"a": 1, "b": 10, "c": 11}
How can I get that final merged dictionary in
z
, notx
?(To be extra-clear, the last-one-wins conflict-handling of
dict.update()
is what I"m looking for as well.)Answer #1:
How can I merge two Python dictionaries in a single expression?
For dictionaries
x
andy
,z
becomes a shallowly-merged dictionary with values fromy
replacing those fromx
.Explanation
Say you have two dictionaries and you want to merge them into a new dictionary without altering the original dictionaries:
x = {"a": 1, "b": 2} y = {"b": 3, "c": 4}
The desired result is to get a new dictionary (
z
) with the values merged, and the second dictionary"s values overwriting those from the first.>>> z {"a": 1, "b": 3, "c": 4}
A new syntax for this, proposed in PEP 448 and available as of Python 3.5, is
z = {**x, **y}
And it is indeed a single expression.
Note that we can merge in with literal notation as well:
z = {**x, "foo": 1, "bar": 2, **y}
and now:
>>> z {"a": 1, "b": 3, "foo": 1, "bar": 2, "c": 4}
It is now showing as implemented in the release schedule for 3.5, PEP 478, and it has now made its way into the What"s New in Python 3.5 document.
However, since many organizations are still on Python 2, you may wish to do this in a backward-compatible way. The classically Pythonic way, available in Python 2 and Python 3.0-3.4, is to do this as a two-step process:
z = x.copy() z.update(y) # which returns None since it mutates z
In both approaches,
y
will come second and its values will replacex
"s values, thusb
will point to3
in our final result.Not yet on Python 3.5, but want a single expression
If you are not yet on Python 3.5 or need to write backward-compatible code, and you want this in a single expression, the most performant while the correct approach is to put it in a function:
def merge_two_dicts(x, y): """Given two dictionaries, merge them into a new dict as a shallow copy.""" z = x.copy() z.update(y) return z
and then you have a single expression:
z = merge_two_dicts(x, y)
You can also make a function to merge an arbitrary number of dictionaries, from zero to a very large number:
def merge_dicts(*dict_args): """ Given any number of dictionaries, shallow copy and merge into a new dict, precedence goes to key-value pairs in latter dictionaries. """ result = {} for dictionary in dict_args: result.update(dictionary) return result
This function will work in Python 2 and 3 for all dictionaries. e.g. given dictionaries
a
tog
:z = merge_dicts(a, b, c, d, e, f, g)
and key-value pairs in
g
will take precedence over dictionariesa
tof
, and so on.Critiques of Other Answers
Don"t use what you see in the formerly accepted answer:
z = dict(x.items() + y.items())
In Python 2, you create two lists in memory for each dict, create a third list in memory with length equal to the length of the first two put together, and then discard all three lists to create the dict. In Python 3, this will fail because you"re adding two
dict_items
objects together, not two lists ->>> c = dict(a.items() + b.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: "dict_items" and "dict_items"
and you would have to explicitly create them as lists, e.g.
z = dict(list(x.items()) + list(y.items()))
. This is a waste of resources and computation power.Similarly, taking the union of
items()
in Python 3 (viewitems()
in Python 2.7) will also fail when values are unhashable objects (like lists, for example). Even if your values are hashable, since sets are semantically unordered, the behavior is undefined in regards to precedence. So don"t do this:>>> c = dict(a.items() | b.items())
This example demonstrates what happens when values are unhashable:
>>> x = {"a": []} >>> y = {"b": []} >>> dict(x.items() | y.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: "list"
Here"s an example where
y
should have precedence, but instead the value fromx
is retained due to the arbitrary order of sets:>>> x = {"a": 2} >>> y = {"a": 1} >>> dict(x.items() | y.items()) {"a": 2}
Another hack you should not use:
z = dict(x, **y)
This uses the
dict
constructor and is very fast and memory-efficient (even slightly more so than our two-step process) but unless you know precisely what is happening here (that is, the second dict is being passed as keyword arguments to the dict constructor), it"s difficult to read, it"s not the intended usage, and so it is not Pythonic.Here"s an example of the usage being remediated in django.
Dictionaries are intended to take hashable keys (e.g.
frozenset
s or tuples), but this method fails in Python 3 when keys are not strings.>>> c = dict(a, **b) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: keyword arguments must be strings
From the mailing list, Guido van Rossum, the creator of the language, wrote:
I am fine with declaring dict({}, **{1:3}) illegal, since after all it is abuse of the ** mechanism.
and
Apparently dict(x, **y) is going around as "cool hack" for "call x.update(y) and return x". Personally, I find it more despicable than cool.
It is my understanding (as well as the understanding of the creator of the language) that the intended usage for
dict(**y)
is for creating dictionaries for readability purposes, e.g.:dict(a=1, b=10, c=11)
instead of
{"a": 1, "b": 10, "c": 11}
Response to comments
Despite what Guido says,
dict(x, **y)
is in line with the dict specification, which btw. works for both Python 2 and 3. The fact that this only works for string keys is a direct consequence of how keyword parameters work and not a short-coming of dict. Nor is using the ** operator in this place an abuse of the mechanism, in fact, ** was designed precisely to pass dictionaries as keywords.Again, it doesn"t work for 3 when keys are not strings. The implicit calling contract is that namespaces take ordinary dictionaries, while users must only pass keyword arguments that are strings. All other callables enforced it.
dict
broke this consistency in Python 2:>>> foo(**{("a", "b"): None}) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() keywords must be strings >>> dict(**{("a", "b"): None}) {("a", "b"): None}
This inconsistency was bad given other implementations of Python (PyPy, Jython, IronPython). Thus it was fixed in Python 3, as this usage could be a breaking change.
I submit to you that it is malicious incompetence to intentionally write code that only works in one version of a language or that only works given certain arbitrary constraints.
More comments:
dict(x.items() + y.items())
is still the most readable solution for Python 2. Readability counts.My response:
merge_two_dicts(x, y)
actually seems much clearer to me, if we"re actually concerned about readability. And it is not forward compatible, as Python 2 is increasingly deprecated.{**x, **y}
does not seem to handle nested dictionaries. the contents of nested keys are simply overwritten, not merged [...] I ended up being burnt by these answers that do not merge recursively and I was surprised no one mentioned it. In my interpretation of the word "merging" these answers describe "updating one dict with another", and not merging.Yes. I must refer you back to the question, which is asking for a shallow merge of two dictionaries, with the first"s values being overwritten by the second"s - in a single expression.
Assuming two dictionaries of dictionaries, one might recursively merge them in a single function, but you should be careful not to modify the dictionaries from either source, and the surest way to avoid that is to make a copy when assigning values. As keys must be hashable and are usually therefore immutable, it is pointless to copy them:
from copy import deepcopy def dict_of_dicts_merge(x, y): z = {} overlapping_keys = x.keys() & y.keys() for key in overlapping_keys: z[key] = dict_of_dicts_merge(x[key], y[key]) for key in x.keys() - overlapping_keys: z[key] = deepcopy(x[key]) for key in y.keys() - overlapping_keys: z[key] = deepcopy(y[key]) return z
Usage:
>>> x = {"a":{1:{}}, "b": {2:{}}} >>> y = {"b":{10:{}}, "c": {11:{}}} >>> dict_of_dicts_merge(x, y) {"b": {2: {}, 10: {}}, "a": {1: {}}, "c": {11: {}}}
Coming up with contingencies for other value types is far beyond the scope of this question, so I will point you at my answer to the canonical question on a "Dictionaries of dictionaries merge".
Less Performant But Correct Ad-hocs
These approaches are less performant, but they will provide correct behavior. They will be much less performant than
copy
andupdate
or the new unpacking because they iterate through each key-value pair at a higher level of abstraction, but they do respect the order of precedence (latter dictionaries have precedence)You can also chain the dictionaries manually inside a dict comprehension:
{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7
or in Python 2.6 (and perhaps as early as 2.4 when generator expressions were introduced):
dict((k, v) for d in dicts for k, v in d.items()) # iteritems in Python 2
itertools.chain
will chain the iterators over the key-value pairs in the correct order:from itertools import chain z = dict(chain(x.items(), y.items())) # iteritems in Python 2
Performance Analysis
I"m only going to do the performance analysis of the usages known to behave correctly. (Self-contained so you can copy and paste yourself.)
from timeit import repeat from itertools import chain x = dict.fromkeys("abcdefg") y = dict.fromkeys("efghijk") def merge_two_dicts(x, y): z = x.copy() z.update(y) return z min(repeat(lambda: {**x, **y})) min(repeat(lambda: merge_two_dicts(x, y))) min(repeat(lambda: {k: v for d in (x, y) for k, v in d.items()})) min(repeat(lambda: dict(chain(x.items(), y.items())))) min(repeat(lambda: dict(item for d in (x, y) for item in d.items())))
In Python 3.8.1, NixOS:
>>> min(repeat(lambda: {**x, **y})) 1.0804965235292912 >>> min(repeat(lambda: merge_two_dicts(x, y))) 1.636518670246005 >>> min(repeat(lambda: {k: v for d in (x, y) for k, v in d.items()})) 3.1779992282390594 >>> min(repeat(lambda: dict(chain(x.items(), y.items())))) 2.740647904574871 >>> min(repeat(lambda: dict(item for d in (x, y) for item in d.items()))) 4.266070580109954
$ uname -a Linux nixos 4.19.113 #1-NixOS SMP Wed Mar 25 07:06:15 UTC 2020 x86_64 GNU/Linux
Resources on Dictionaries
Answer #2:
In your case, what you can do is:
z = dict(list(x.items()) + list(y.items()))
This will, as you want it, put the final dict in
z
, and make the value for keyb
be properly overridden by the second (y
) dict"s value:>>> x = {"a":1, "b": 2} >>> y = {"b":10, "c": 11} >>> z = dict(list(x.items()) + list(y.items())) >>> z {"a": 1, "c": 11, "b": 10}
If you use Python 2, you can even remove the
list()
calls. To create z:>>> z = dict(x.items() + y.items()) >>> z {"a": 1, "c": 11, "b": 10}
If you use Python version 3.9.0a4 or greater, then you can directly use:
x = {"a":1, "b": 2} y = {"b":10, "c": 11} z = x | y print(z)
{"a": 1, "c": 11, "b": 10}
Answer #3:
An alternative:
z = x.copy() z.update(y)
Answer #4:
Another, more concise, option:
z = dict(x, **y)
Note: this has become a popular answer, but it is important to point out that if
y
has any non-string keys, the fact that this works at all is an abuse of a CPython implementation detail, and it does not work in Python 3, or in PyPy, IronPython, or Jython. Also, Guido is not a fan. So I can"t recommend this technique for forward-compatible or cross-implementation portable code, which really means it should be avoided entirely.Answer #5:
This probably won"t be a popular answer, but you almost certainly do not want to do this. If you want a copy that"s a merge, then use copy (or deepcopy, depending on what you want) and then update. The two lines of code are much more readable - more Pythonic - than the single line creation with .items() + .items(). Explicit is better than implicit.
In addition, when you use .items() (pre Python 3.0), you"re creating a new list that contains the items from the dict. If your dictionaries are large, then that is quite a lot of overhead (two large lists that will be thrown away as soon as the merged dict is created). update() can work more efficiently, because it can run through the second dict item-by-item.
In terms of time:
>>> timeit.Timer("dict(x, **y)", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 15.52571702003479 >>> timeit.Timer("temp = x.copy() temp.update(y)", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 15.694622993469238 >>> timeit.Timer("dict(x.items() + y.items())", "x = dict(zip(range(1000), range(1000))) y=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000) 41.484580039978027
IMO the tiny slowdown between the first two is worth it for the readability. In addition, keyword arguments for dictionary creation was only added in Python 2.3, whereas copy() and update() will work in older versions.