Python:Can anybody explain me this one line code? - python

print(''.join(map(str,range(1,n+1))))
Like what is str doing here ? and how is this outputting in the single line ?i know what map and join does but still i'm not clear with this whole code

numbers_one_to_n = range(1,n+1)
numbers_as_strings = map(str, numbers_one_to_n)
numbers_joined_to_single_string = ''.join(numbers_as_strings)
print(numbers_joined_to_single_string)

print(''.join(map(str,range(1,n+1))))
You say you know what map does? The documentation says:
map(function, iterable, ...)
Return an iterator that applies function to every item of iterable, yielding the result.
So str is the function. The iterable is the range of integers (in Python 3 this is a range object`)
str returns a string object generated from its argument.
So, str is called for each integer in the range.
An alternative to map is a list comprehension, which some prefer:
print(''.join([str(i) for i in range(1,n+1)]))

'' is a separator, that used between the concatenating elements (strings in a string sequence or characters in a string). For instance:
>>> '-'.join(('foo', 'bar'))
'foo-bar'
>>> '-'.join('bar')
'b-a-r'
str is a type and the function to convert to this type.
So, map(str, list_of_integers) converts this list to a list of strings. Because map applies the function to each element of input list to get output list.
So, we have the range from 1 to (n + 1), that have been converted to the list of the strings, and then this list have been concatenated with the empty slitter ''.

Related

Why str([1]) = [1] and not "1" in python

str([1]) = [1]
If we apply type conversion on the str([1]), why don't we get the answer = "1".
There is no type conversion here. str is a builtin function that takes any object, and produces a string representation of it (typically using the __str__ method of the object).
Here, the argument to str is a list [1], and the __str__ method of list converts its elements to strings (using repr), joins them with commas, and surrounds them with square brackets [].
first of all use str() in python ;)
str cast the parameter you give into a string. So when the parameter is an array, it returns you "[1]". You can see the type of the result with type(param), it'll be a string and if you print res[0] it'll give you "["
If you wanna get ride of the [] you can use the code bellow for example :
print(s.replace('[', '').replace(']', ''))

assign a string to an empty list to convert to a char wise list, how to understand?

To convert a string to char-wise list, one way is to assign the string to an empty list. However, the physical process on the memory is unclear to me. Any help is appreciated.
An example
s = 'abc'
s_list = []
s_list[:5] = s
print(s_list)
The code will output:
['a', 'b', 'c']
Basically, I would like to understand:
Why there is no out of index error when you try to do slicing s_list[:5] on an empty list? As a matter of fact, you can do s_list[:] or s_list[x:] or s_list[:x] (x can be any integer), it wouldn't raise any error.
I would like to know what's happening at the assignment sign for s_list[:5] = s. Does Python do a automatic conversion from string to list before assign to s_list?
documentation of python std library, paragraph on sequence types
https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
see footnote #4
I believe that taking a slice of an existing list and assigning to it some iterable (including string) will use values of that iterable to fill the slice, e.g.
l=[];
l[0:5] = range(5);

different behavior in Python when creating set from constructor or literal

I am trying to create a Set structure in Python by using code below:
a = set ([1,2,3])
print (a)
a ={1,2,3}
print (a)
a = {'FG'}
print (a)
a = set('FG')
print (a)
output:
{1, 2, 3}
{1, 2, 3}
{'FG'}
{'F', 'G'}
while the set creation with a list of numbers leads to the same result using the two options,
I see that if the input type is a String the result that I expect is the second, i.e. create a set of characters, while the first result seems to ignore that a string is a sequence of characters, therefore I am confused.
The set() constructor takes an iterable as an argument and will create a set of each unique item in that iterable. In this case a string IS the iterable, so you are seeing a set composed of each character in the string.
To get a set strings, places the strings in a list or tuple.
set(['abc', 'efg'])
When you do a = {'FG'}, you define the set with one single element which is the string "FG".
Then, when you do a = set('FG'), you define a set using an iterable, but in that case the iterable is not a list but a string. The set function will find all unique elements in the specified iterable, so in that case it will find all unique characters in the given string.
If you wanted the two to output the same result, you would have to give the set function a list containing individual strings, for instance: a = set(["FG"]).
When passing integers, you're passing it in the form of a list.
>>>a=set([1,2,3])
>>>print(a)
{1,2,3}
Whereas you're not passing the string in list,
>>>a=set('FG')
>>>print(a)
{'F','G'}
so python interprets both of them differently.
If you pass the string as a list, the result would be similar to that of integer.
>>> a=set(['FG'])
>>> print(a)
{'FG'}
set() takes iterables as input.
The set constructor takes an iterable and adds each element of the iterable object to the set. So when you construct the set with the iterable list [1,2,3], you naturally end up with {1, 2, 3}.
A string is actually iterable:
for i in 'abc':
print(i)
Prints:
a
b
c
Iterating over a string returns each character of the string for each iteration. So when you construct a set with a string (which you can do because it is an iterable), you end up with a set where each character becomes a separate member of the set:
set('FG') -> {'F', 'G'}
But when you are creating a set by using a literal and not invoking a constructor, as in {'FG'}, you are just creating a set with a single member 'FG'.

Strings are lists but i cannot use list methods on them like append or replace. Why?

I'm a beginner and I'm trying to make a palindrome from a user input. I was thinking I could use .replace() but I got an error that 'str' object has no attribute 'append'. I thought strings were lists? So why don't list methods work on them?
Strings are not lists, they are sequences. They share some of the same behaviors as lists, but they are not themselves lists. Strings are immutable objects.
You can convert a string to a list by passing the string to list:
data = list("some string")
You can then operate on data, and convert it back to a string later with join:
new_string = "".join(data)
If you simply want to add a character to a string you can use concatenation:
new_string = "abc" + "d"
Strings are a distinct class from Lists. As the error says, Strings don't have an append method.
append wouldn't make sense for Strings anyways, as they're immutable. They can't be modified in place like lists can.
If you want to "append" a Character, just use concatenation, and reassign the String:
x = "String" + "s"
Tl;dr: strings != lists.
You can index individual characters in strings, like you can index elements in lists, but there is a difference in mutability.
If something is mutable, it can change. Lists are mutable so you can change the contents of them (either adding, removing or changing elements).
See some examples that I am sure you are familiar with:
>>> l = [1, 2, 3]
>>> l[0] = 9
>>> l.append(8)
>>> l
[9, 2, 3, 8]
On the other hand, strings are immutable so can not change. This means that there are no append or equivalent methods. However, you can concatenate two of them to form a new string, but this is a different operation in terms of memory (appending modifies the current space in memory, concatenation assigns a whole new space in memory to the new string).
So here are some examples with strings:
>>> s = "abcdef"
>>> s += "ghi"
>>> s
'abcdefghi'
>>> s[0] = "z"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
To get things clear, str and list are two different data types.
One basic difference between str's and lists is that lists can any type of data i.e. integers, characters, dictionary or another list etc., while strings can only hold a set of characters(alphabets numbers or any special characters).
Also, lists are mutable and string are immutable!
Reference.
To get to know what methods can be used with a string dir(str) and dir(list) would help!
You can use Python's type() method to figure out what type the object is:
>>> type("String")
<class 'str'>
You can also turn the string into a list using the list method:
>>> type(list("String"))
<class 'list'>

python struct.pack(): pack multiple datas in a list or a tuple

Say i have a list or a tuple containing numbers of type long long,
x = [12974658, 638364, 53637, 63738363]
If want to struct.pack them individually, i have to use
struct.pack('<Q', 12974658)
or if i want to do it as multiple, then i have to explicitly mention it like this
struct.pack('<4Q', 12974658, 638364, 53637, 63738363)
But, how can i insert items in a list or tuple inside a struct.pack statement. I tried using for loop like this.
struct.pack('<4Q', ','.join(i for i in x))
got error saying expected string, int found, so i converted the list containing type int into str, now it gets much more complicated to pack them. Because the whole list gets converted into a string( like a single sentence).
As of now im doing some thing like
binary_data = ''
x = [12974658, 638364, 53637, 63738363]
for i in x:
binary_data += struct.pack('<Q', i)
And i unpack them like
struct.unpack('<4Q', binary_data)
My question: is there a better way around, like can i directly point a list or tuple inside the struct.pack statement, or probably a one liner ?
You can splat, I'm sorry "unpack the argument list":
>>> struct.pack("<4Q", *[1,2,3,4])
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
If the length of the list is dynamic, you can of course build the format string at runtime too:
>>> x = [1, 2] # This could be any list of integers, of course.
>>> struct.pack("<%uQ" % len(x), *x)
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'

Categories

Resources