Why is a[:]=1 fundamentally different to a[:]='1'? - python

Please consider the two snippets of code (notice the distinction between string and integer):
a = []
a[:] = '1'
and
a = []
a[:] = 1
In the first case a is ['1']. In the second, I get the error TypeError: can only assign an iterable. Why would using '1' over 1 be fundamentally different here?

Assigning to a slice requires an iterable on the right-hand side.
'1' is iterable, while 1 is not. Consider the following:
In [7]: a=[]
In [8]: a[:]='abc'
The result is:
In [9]: a
Out[9]: ['a', 'b', 'c']
As you can see, the list gets each character of the string as a separate item. This is a consequence of the fact that iterating over a string yields its characters.
If you want to replace a range of a's elements with a single scalar, simply wrap the scalar in an iterable of some sort:
In [11]: a[:]=(1,) # single-element tuple
In [12]: a
Out[12]: [1]
This also applies to strings (provided the string is to be treated as a single item and not as a sequence of characters):
In [17]: a[:]=('abc',)
In [18]: a
Out[18]: ['abc']

'1' is a string, but it is iterable. It is like a list of characters. a[:]='1' replaces the contents of the list a with the content of the string '1'. But 1 is an integer.
Python does not change the type.
Example:
print bool(1=='1') # --> False

Related

python: comparing list of tuple

Just wondering the following:
print [()] == list(tuple()) # prints False
The first is a list containing an empty tuple, the second is an empty list.
Why this code prints False instead of True (same result in python 2 and 3)?
Thanks in advance!
You compared a list with one element (an empty tuple) with an empty list. list(tuple()) does not do what you think it does.
That's because list(object) does not produce a list with that one object as an element. list() converts the object, which must be iterable, to a list. It copies the elements out of the object:
>>> dictionary = {'foo': 'bar'}
>>> list(dictionary) # iteration over a dictionary produces keys
['foo']
You gave it an empty tuple, so the result is an empty list:
>>> empty = ()
>>> list(empty)
[]
tuple() does the same thing, by the way. And both list() and tuple() without an argument produce an empty object.

Python Function returning string with quotes

I have a function and returning three values, The return value for my function is
(1, 3, "<class 'int'>")
while I want to return
(1, 3, <class 'int'>)
How do I remove the quotes from my return value.str(type(element)) is the value which is returning the 3rd value
def is_list_permutation(L1, L2):
L1set = set(L1)
L2set = set(L2)
count = 0
element = ''
if L1 == [] and L2 == []:
return(None,None,None)
elif len(L1) == len(L2) and L1set == L2set:
for a in L1:
if L1.count(a) == L2.count(a):
if L1.count(a) > count:
count = L1.count(a)
element = a
return(element,count,str(type(element)))
else:
return False
break
else:
return False
so if i give
L1 = [1, 'b', 1, 'c', 'c', 1]
L2 = ['c', 1, 'b', 1, 1, 'c']
then the result is (1, 3, "<class 'int'>") while I want (1, 3, <class 'int'>)
Your function is returning a tuple with three elements: element, count and the string representation of the type of element. At no point, this has any string representation which you’re seeing there. You just get back a tuple.
Now, when you print that tuple, then the print function will actually try to convert it into a string. For a tuple, this string representation is defined to be a set of parentheses (), and the repr() string representation of each tuple element inside.
For numbers, this will look fine since repr(5) happens to be the string '5'. But for strings, the repr will add quotes to make sure that the return string would be valid Python code:
>>> repr('foo')
"'foo'"
>>> print(repr('foo'))
'foo'
Now, when you say, you want the result without those quotes, you have to think about what that actually means. You could easily format the result string yourself. For example like this:
return '({0}, {1}, {2})'.format(element, count, str(type(element)))
This will return a string that would look like the way you want.
However, by doing that, you also lose the information you had when you returned a tuple. Now, you just return a string that has no information about the actual source values. So you cannot take the count value out without parsing the string again.
So, think about what you want to do: Do you actually just want something nice to print, or do you actually want to get those three values individually as a return value to be able to use them for something else afterwards?
You could always consider printing the text in the desired format later, if you already have the return values as a tuple…
Btw.: Note that when not calling str(type(element)) but just type(element), you would get back a type element (instead of a string). And the repr() of a type element happens to be exactly what you would want to have. So as a quick fix, you could always get rid of that str() call there.
There will always be some quotes around it because it is a string!
If you want to return None when the string is "" then you could do this:
x = str(type(s))
return(element, count, x if x else None)

How to create a tuple of an empty tuple in Python?

How can I create a tuple consisting of just an empty tuple, i.e. (())? I have tried tuple(tuple()), tuple(tuple(tuple())), tuple([]) and tuple(tuple([])) which all gave me ().
The reason that I use such a thing is as follows: Assume you have n bags with m items. To represent a list of items in a bag, I use a tuple of length n where each element of that tuple is a representative for a bag. A bag might be empty, which is labeled by (). Now, at some initial point, I have just one bag with empty items!
The empty tuple is () (or the more-verbose and slower tuple()), and a tuple with just one item (such as the integer 1), called a singleton (see here and here) is (1,). Therefore, the tuple containing only the empty tuple is
((),)
Here are some results showing that works:
>>> a=((),)
>>> type(a)
<type 'tuple'>
>>> len(a)
1
>>> a[0]
()
>>> type(a[0])
<type 'tuple'>
>>> len(a[0])
0
I'm not surprised this (()) didn't work, since the outer parentheses get interpreted as that - parentheses. So (()) == (), just like (2) == 2. This should work, however:
((),)
An empty tuple:
my_tuple = ()
A tuple with 1 string:
my_tuple = ('foo',)
A tuple with 2 strings:
my_tuple = ('foo', 'bar')
A tuple with 1 empty tuple:
my_tuple = ((),)
A tuple with 2 empty tuples:
my_tuple = ((), ())
in Python 2, tuple() is the only genuine empty tuple, but (), and ((),) create a tuple of length 1 that contains a tuple of length 0 - but not a tuple of length zero itself.
If you want an answer to "how do I create an empty (or zero length) tuple.... I found this post with the search "how to create an empty tuple", then realized this was not the same question, but could be mistaken for that question (as the search does), so I though I would provide the answer to :
How do you simply create an empty tuple?
the original question could mislead you, as the original answers are almost good enough as an empty tuple, but do fail one test.
(), will create an 'empty' tuple as suggested in previous answers with ((),) which will also work, as will ((( ((( (),))) ))) in fact you can use any number of outer brackets you choose, they just work as brackets. However, python, when printing a tuple, does add one set of outer brackets.
empty brackets is a non-standard representation of 'no value' and adding the trailing comma makes a tuple from 'no value'. But it is a tuple with a 'no value' entry, not an empty tuple.
Note: This is not a zero length tuple, as the other examples have also shown. The outer tuple is a tuple with one value, just that value has itself, is the empty tuple. So this creates an empty tuple inside another tuple, and the other tuple is not empty. For a true empty tuple by itself, use tuple() although the (), behaves some what similar, it is not quite correct.
>>> a = (),
>>> type(a)
<class 'tuple'>
>>> len(a)
1
>>> a
((),)
>>> len(a[0]) # the inside tuple is empty, just not the outside one
0
Similarly, for a tuple of length 1 but with a value (of zero in the case of b, and "" for the example with c)
>>> b = 0,
>>> type(b)
<class 'tuple'>
>>> len(b)
1
>>>b
(0,)
# now with an empty string
>>> c = "",
>>> type(c)
<class 'tuple'>
>>> len(c)
1
>>>c
('',)
>>> len (c[0]) # same len of c[0] as with 'empty' tuple
0
So the outer brackets are included for displaying a tuple, but not actually part of the tuple, nor needed for creating the tuple.
However all these brackets methods are not a real empty at the outer level, which is something that also has use cases.
>>> a = ((),) # extra brackets just to show same as other answers
>>> len(a)
1
>>> if a:
print("not empty")
not empty
>>> e = tuple()
>>> len(e)
0
>>> type(e)
<class 'tuple'>
>>> if e:
print("not empty")
>>> # note...did not print...so e acts as false as an empty tuple should
So if you really need a genuine empty tuple, use tuple(), but if near enough is all you need, you can use (), or ((),)
In the general case, it's the commas that make tuples, not the parentheses. Things become confusing in the case of empty tuples because a standalone comma is syntactically incorrect. So for the special case of an empty tuple, the "it is commas that make tuples" rule does not apply, and the special case () syntax is used instead.

How to get the first 2 letters of a string in Python?

Let's say I have a string
str1 = "TN 81 NZ 0025"
two = first2(str1)
print(two) # -> TN
How do I get the first two letters of this string? I need the first2 function for this.
It is as simple as string[:2]. A function can be easily written to do it, if you need.
Even this, is as simple as
def first2(s):
return s[:2]
In general, you can get the characters of a string from i until j with string[i:j].
string[:2] is shorthand for string[0:2]. This works for lists as well.
Learn about Python's slice notation at the official tutorial
t = "your string"
Play with the first N characters of a string with
def firstN(s, n=2):
return s[:n]
which is by default equivalent to
t[:2]
Heres what the simple function would look like:
def firstTwo(string):
return string[:2]
In python strings are list of characters, but they are not explicitly list type, just list-like (i.e. it can be treated like a list). More formally, they're known as sequence (see http://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange):
>>> a = 'foo bar'
>>> isinstance(a, list)
False
>>> isinstance(a, str)
True
Since strings are sequence, you can use slicing to access parts of the list, denoted by list[start_index:end_index] see Explain Python's slice notation . For example:
>>> a = [1,2,3,4]
>>> a[0]
1 # first element, NOT a sequence.
>>> a[0:1]
[1] # a slice from first to second, a list, i.e. a sequence.
>>> a[0:2]
[1, 2]
>>> a[:2]
[1, 2]
>>> x = "foo bar"
>>> x[0:2]
'fo'
>>> x[:2]
'fo'
When undefined, the slice notation takes the starting position as the 0, and end position as len(sequence).
In the olden C days, it's an array of characters, the whole issue of dynamic vs static list sounds like legend now, see Python List vs. Array - when to use?
All previous examples will raise an exception in case your string is not long enough.
Another approach is to use
'yourstring'.ljust(100)[:100].strip().
This will give you first 100 chars.
You might get a shorter string in case your string last chars are spaces.
For completeness: Instead of using def you could give a name to a lambda function:
first2 = lambda s: s[:2]

"in" statement behavior in lists vs. strings

In Python, asking if a substring exists in a string is pretty straightforward:
>>> their_string = 'abracadabra'
>>> our_string = 'cad'
>>> our_string in their_string
True
However, checking if these same characters are "in" a list fails:
>>> ours, theirs = map(list, [our_string, their_string])
>>> ours in theirs
False
>>> ours, theirs = map(tuple, [our_string, their_string])
>>> ours in theirs
False
I wasn't able to find any obvious reason why checking for elements "in" an ordered (even immutable) iterable would behave differently than a different type of ordered, immutable iterable.
For container types such as lists and tuples, x in container checks if x is an item in the container. Thus with ours in theirs, Python checks if ours is an item in theirs and finds that it is False.
Remember that a list could contain a list. (e.g [['a','b','c'], ...])
>>> ours = ['a','b','c']
>>> theirs = [['a','b','c'], 1, 2]
>>> ours in theirs
True
Are you looking to see if 'cad' is in any of the strings in a list of strings? That would like something like:
stringsToSearch = ['blah', 'foo', 'bar', 'abracadabra']
if any('cad' in s for s in stringsToSearch):
# 'cad' was in at least one string in the list
else:
# none of the strings in the list contain 'cad'
From the Python documentation, https://docs.python.org/2/library/stdtypes.html for sequences:
x in s True if an item of s is equal to x, else False (1)
x not in s False if an item of s is equal to x, else True (1)
(1) When s is a string or Unicode string object the in and not in operations act like a substring test.
For user defined classes, the __contains__ method implements this in test. list and tuple implement the basic notion. string has the added notion of 'substring'. string is a special case among the basic sequences.

Categories