mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-25 20:44:24 +01:00
Add new example: Tricky strings
Closes https://github.com/satwikkansal/wtfpython/issues/54
This commit is contained in:
parent
1ec3c5e5e9
commit
b743451660
41
README.md
vendored
41
README.md
vendored
@ -423,14 +423,52 @@ SyntaxError: EOL while scanning string literal
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### String interning
|
### Strings can be tricky sometimes
|
||||||
|
|
||||||
|
1\.
|
||||||
```py
|
```py
|
||||||
>>> a = "some_string"
|
>>> a = "some_string"
|
||||||
>>> id(a)
|
>>> id(a)
|
||||||
140420665652016
|
140420665652016
|
||||||
>>> id("some" + "_" + "string") # Notice that both the ids are same.
|
>>> id("some" + "_" + "string") # Notice that both the ids are same.
|
||||||
140420665652016
|
140420665652016
|
||||||
|
```
|
||||||
|
|
||||||
|
2\.
|
||||||
|
```py
|
||||||
|
>>> a = "wtf"
|
||||||
|
>>> b = "wtf"
|
||||||
|
>>> a is b
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> a = "wtf!"
|
||||||
|
>>> b = "wtf!"
|
||||||
|
>>> a is b
|
||||||
|
False
|
||||||
|
```
|
||||||
|
|
||||||
|
3\.
|
||||||
|
```py
|
||||||
|
>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
|
||||||
|
True
|
||||||
|
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
|
||||||
|
```
|
||||||
|
|
||||||
|
Makes sense, right?
|
||||||
|
|
||||||
|
#### 💡 Explanation:
|
||||||
|
+ Such behavior is due to CPython optimization (called string interning) that tries to use existing immutable objects in some cases rather than creating a new object every time.
|
||||||
|
+ After being interned, many variables may point to the same string object in memory (thereby saving memory).
|
||||||
|
+ In the snippets above, strings are implicity interned. The decison of when to implicitly intern a string is implementation dependent. There are some facts that can be used to guess if a string will be interned or not:
|
||||||
|
* All length 0 and length 1 strings are interned.
|
||||||
|
* Strings are interned at compile time (`'wtf'` will be interned but `''.join(['w', 't', 'f']` will not be interned)
|
||||||
|
* Strings that are not composed of ascii letters, digits or underscores, are not interned. This explains why `'wtf!'` was not interned due to `!`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `+=` is faster
|
||||||
|
|
||||||
|
```py
|
||||||
# using "+", three strings:
|
# using "+", three strings:
|
||||||
>>> timeit.timeit("s1 = s1 + s2 + s3", setup="s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000", number=100)
|
>>> timeit.timeit("s1 = s1 + s2 + s3", setup="s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000", number=100)
|
||||||
0.25748300552368164
|
0.25748300552368164
|
||||||
@ -441,7 +479,6 @@ SyntaxError: EOL while scanning string literal
|
|||||||
|
|
||||||
#### 💡 Explanation:
|
#### 💡 Explanation:
|
||||||
+ `+=` is faster than `+` for concatenating more than two strings because the first string (example, `s1` for `s1 += s2 + s3`) is not destroyed while calculating the complete string.
|
+ `+=` is faster than `+` for concatenating more than two strings because the first string (example, `s1` for `s1 += s2 + s3`) is not destroyed while calculating the complete string.
|
||||||
+ Both the strings refer to the same object because of CPython optimization that tries to use existing immutable objects in some cases (implementation specific) rather than creating a new object every time. You can read more about this [here](https://stackoverflow.com/questions/24245324/about-the-changing-id-of-an-immutable-string).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user