If not having a value has a meaning in your program (e.g. an optional value), you should use None. That's its purpose anyway.
If the value must be provided by the caller of __init__, I would recommend not to initialize it.
If "" makes sense as a default value, use it.
In Python the type is deduced from the usage. Hence, you can change the type by just assigning a value of another type.
>>> x = None
>>> print type(x)
<type 'NoneType'>
>>> x = "text"
>>> print type(x)
<type 'str'>
>>> x = 42
>>> print type(x)
<type 'int'>
Answer from wierob on Stack OverflowIf not having a value has a meaning in your program (e.g. an optional value), you should use None. That's its purpose anyway.
If the value must be provided by the caller of __init__, I would recommend not to initialize it.
If "" makes sense as a default value, use it.
In Python the type is deduced from the usage. Hence, you can change the type by just assigning a value of another type.
>>> x = None
>>> print type(x)
<type 'NoneType'>
>>> x = "text"
>>> print type(x)
<type 'str'>
>>> x = 42
>>> print type(x)
<type 'int'>
Another way to initialize an empty string is by using the built-in str() function with no arguments.
str(object='')
Return a string containing a nicely printable representation of an object.
...
If no argument is given, returns the empty string, ''.
In the original example, that would look like this:
def __init__(self, mystr=str())
self.mystr = mystr
Personally, I believe that this better conveys your intentions.
Notice by the way that str() itself sets a default parameter value of ''.
Videos
Total curiosity, but is there a way I can do this better:
player_inputs = ["", ""]
I want to have a list of 2 strings, but the strings will be inputed later. I thought I could do this:
player_inputs = [str, str]
but that doesn't work, not sure why.
import random
def shuffle(string):
templist = list(string)
random.shuffle(templist)
return "".join(templist)
usablelower = chr(random.randint(97, 122))
usableupper = chr(random.randint(65, 90))
usablenum = chr(random.randint(48, 57))
rst = random.choice(usableupper)
rst1 = random.choice(usablelower)
rst2 = random.choice(usablenum)
pw = rst1 + rst + rst2 + rst + rst2 + rst1
pw = shuffle(pw)
print(pw)Hello, I was trying to code a random password generator yet I could not understand the "return "".join(templist)" part. What is the use of empty string here, what does it do and why this code require it?
See the Python standard types page:
>>> [''] * 16
['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
s * n, n * s
n shallow copies of s concatenated
where s is a sequence and n is an integer.
The full footnote from the docs for this operation:
Values of n less than 0 are treated as 0 (which yields an empty sequence of the same type as s). Note also that the copies are shallow; nested structures are not copied. This often haunts new Python programmers; consider:
>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]
What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]] * 3 are (pointers to) this single empty list. Modifying any of the elements of lists modifies this single list. You can create a list of different lists this way:
>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]
You can multiply out a list like this. Since '' is immutable you don't need to worry that they are all references to the same string.
[''] * 16
You can't use the same trick for mutable objects (eg lists or dicts). You need to use something like your last version
[mutable_thing() for c in range(16)]
or
[[] for c in range(16)]
or
[{} for c in range(16)]