how to assign string input as list in python - python

User is giving list as input [1,2,3,4]:
a = input()
It is taking this as str.
I want to get this data into local list b.
b = a.strip('][').split(', ')
print(b)
Output: ['1,2,3,4']
How to get list individually not a single entity?

You should do .split(',') instead of .split(', ')

You can use ast.literal_eval to do so.
import ast
a = input()
b = ast.literal_eval(a)
print(b)
# output
[1, 2, 3, 4]
From the docs:
Safely evaluate an expression node or a string containing a Python
literal or container display. The string or node provided may only
consist of the following Python literal structures: strings, bytes,
numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis.
This can be used for safely evaluating strings containing Python
values from untrusted sources without the need to parse the values
oneself. It is not capable of evaluating arbitrarily complex
expressions, for example involving operators or indexing.

the problem is that in the line:
b = a.strip('][').split(', ')
you used ', ' with whitespace instead of ',' without whitespace
because your input does not have any spaces as shown below:
user is giving list as input [1,2,3,4]

ast.literal_eval(a) gets the string input as a list datatype, which can be converted into a list of individual strings with map:
import ast
b = list(map(str,ast.literal_eval(a)))
['1', '2', '3', '4']

Related

back slash in token key [duplicate]

In Python, when I print a string with a backslash, it prints the backslash only once:
>>> print(r'C:\hi')
C:\hi
>>> print('C:\\hi')
C:\hi
But I noticed that when you print a tuple of strings with backslashes, it prints a double backslash:
>>> print((r'C:\hi', 'C:\\there'))
('C:\\hi', 'C:\\there')
Why does it behave differently when printing the tuple?
(Note, this happens in both Python 2 and 3, and in both Windows and Linux.)
When you print a tuple (or a list, or many other kinds of items), the representation (repr()) of the contained items is printed, rather than the string value. For simpler types, the representation is generally what you'd have to type into Python to obtain the value. This allows you to more easily distinguish the items in the container from the punctuation separating them, and also to discern their types. (Think: is (1, 2, 3) a tuple of three integers, or a tuple of a string "1, 2" and an integer 3—or some other combination of values?)
To see the repr() of any string:
print(repr(r'C:\hi'))
At the interactive Python prompt, just specifying any value (or variable, or expression) prints its repr().
To print the contents of tuples as regular strings, try something like:
items = (r'C:\hi', 'C:\\there')
print(*items, sep=", ")
str.join() is also useful, especially when you are not printing but instead building a string which you will later use for something else:
text = ", ".join(items)
However, the items must be strings already (join requires this). If they're not all strings, you can do:
text = ", ".join(map(str, items))

Python 3 split()

When I'm splitting a string "abac" I'm getting undesired results.
Example
print("abac".split("a"))
Why does it print:
['', 'b', 'c']
instead of
['b', 'c']
Can anyone explain this behavior and guide me on how to get my desired output?
Thanks in advance.
As #DeepSpace pointed out (referring to the docs)
If sep is given, consecutive delimiters are not grouped together and are deemed to delimit empty strings (for example, '1,,2'.split(',') returns ['1', '', '2']).
Therefore I'd suggest using a better delimiter such as a comma , or if this is the formatting you're stuck with then you could just use the builtin filter() function as suggested in this answer, this will remove any "empty" strings if passed None as the function.
sample = 'abac'
filtered_sample = filter(None, sample.split('a'))
print(filtered_sample)
#['b', 'c']
When you split a string in python you keep everything between your delimiters (even when it's an empty string!)
For example, if you had a list of letters separated by commas:
>>> "a,b,c,d".split(',')
['a','b','c','d']
If your list had some missing values you might leave the space in between the commas blank:
>>> "a,b,,d".split(',')
['a','b','','d']
The start and end of the string act as delimiters themselves, so if you have a leading or trailing delimiter you will also get this "empty string" sliced out of your main string:
>>> "a,b,c,d,,".split(',')
['a','b','c','d','','']
>>> ",a,b,c,d".split(',')
['','a','b','c','d']
If you want to get rid of any empty strings in your output, you can use the filter function.
If instead you just want to get rid of this behavior near the edges of your main string, you can strip the delimiters off first:
>>> ",,a,b,c,d".strip(',')
"a,b,c,d"
>>> ",,a,b,c,d".strip(',').split(',')
['a','b','c','d']
In your example, "a" is what's called a delimiter. It acts as a boundary between the characters before it and after it. So, when you call split, it gets the characters before "a" and after "a" and inserts it into the list. Since there's nothing in front of the first "a" in the string "abac", it returns an empty string and inserts it into the list.
split will return the characters between the delimiters you specify (or between an end of the string and a delimiter), even if there aren't any, in which case it will return an empty string. (See the documentation for more information.)
In this case, if you don't want any empty strings in the output, you can use filter to remove them:
list(filter(lambda s: len(s) > 0, "abac".split("a"))

How to replace multiple substrings in a list?

I need to turn the input_string into the comment below using a for loop. First I sliced it using the split() function, but now I need to somehow turn the input string into ['result1', 'result2', 'result3', 'result5']. I tried replacing the .xls and the dash for nothing (''), but the string output is unchanged. Please don't import anything, I'm trying to do this with functions and loops only.
input_string = "01-result.xls,2-result.xls,03-result.xls,05-result.xls"
# Must be turned into ['result1','result2', 'result3', 'result5']
splitted = input_string.split(',')
for c in ['.xls', '-', '0']:
if c in splitted:
splitted = splitted.replace(splitted, 'c', '')
When I type splitted, the output is ['01-result.xls', '2-result.xls', '03-result.xls', '05-result.xls'] therefore nothing is happening.
Use the re module's sub function and split.
>>> input_string = "01-result.xls,2-result.xls,03-result.xls,05-result.xls"
>>> import re
>>> re.sub(r'(\d+)-(\w+)\.xls',r'\2\1',input_string)
'result01,result2,result03,result05'
>>> re.sub(r'(\d+)-(\w+)\.xls',r'\2\1',input_string).split(',')
['result01', 'result2', 'result03', 'result05']
Using no imports, you can use a list comprehension
>>> [''.join(x.split('.')[0].split('-')[::-1]) for x in input_string.split(',')]
['result01', 'result2', 'result03', 'result05']
The algo here is, we loop through the string after splitting it on ,. Now we split the individual words on . and the first element of these on -. We now have the number and the words, which we can easily join.
Complete explanation of the list comp answer -
To understand what a list comprehension is, Read What does "list comprehension" mean? How does it work and how can I use it?
Coming to the answer,
Splitting the input list on ,, gives us the list of individual file names
>>> input_string.split(',')
['01-result.xls', '2-result.xls', '03-result.xls', '05-result.xls']
Now using the list comprehension construct, we can iterate through this,
>>> [i for i in input_string.split(',')]
['01-result.xls', '2-result.xls', '03-result.xls', '05-result.xls']
As we need only the file name and not the extension, we split by using . and take the first value.
>>> [i.split('.')[0] for i in input_string.split(',')]
['01-result', '2-result', '03-result', '05-result']
Now again, what we need is the number and the name as two parts. So we again split by -
>>> [i.split('.')[0].split('-') for i in input_string.split(',')]
[['01', 'result'], ['2', 'result'], ['03', 'result'], ['05', 'result']]
Now we have the [number, name] in a list, However the format that we need is "namenumber". Hence we have two options
Concat them like i.split('.')[0].split('-')[1]+i.split('.')[0].split('-')[0]. This is an unnecessarily long way
Reverse them and join. We can use slices to reverse a list (See How can I reverse a list in python?) and str.join to join like ''.join(x.split('.')[0].split('-')[::-1]).
So we get our final list comprehension
>>> [''.join(x.split('.')[0].split('-')[::-1]) for x in input_string.split(',')]
['result01', 'result2', 'result03', 'result05']
Here's a solution using list comprehension and string manipulation if you don't want to use re.
input_string = "01-result.xls,2-result.xls,03-result.xls,05-result.xls"
# Must be turned into ['result1','result2', 'result3', 'result5']
splitted = input_string.split(',')
#Remove extension, then split by hyphen, switch the two values,
#and combine them into the result string
print ["".join(i.split(".")[0].split("-")[::-1]) for i in splitted]
#Output
#['result01', 'result2', 'result03', 'result05']
The way this list comprehension works is:
Take the list of results and remove the ".xls". i.split(".)[0]
Split on the - and switch positions of the number and "result". .split("-")[::-1]
For every item in the list, join the list into a string. "".join()

list with numbers and strings to single string python

How do I print a list that has numbers and strings to a single string?
For example, I have this list: ["(",3,"+",4,"-",3,")"], I would like it to be printed as :(3+4-4). I tried to use the join command, but I keep having issues with the numbers.
You have to cast the ints to str, str.join expects strings:
l = ["(",3,"+",4,"-",3,")"]
print("".join(map(str,l)))
(3+4-3)
Which is equivalent to:
print("".join([str(x) for x in l]))
To delimit each element with a space use:
print(" ".join(map(str,l)))

Using Python to break a continuous string into components?

This is similar to what I want to do: breaking a 32-bit number into individual fields
This is my typical "string" 00000000110000000000011000000000
I need to break it up into four equal parts:
00000000
11000000
00000110
00000000
I need to append the list to a new text file with the original string as a header.
I know how to split the string if there were separators such as spaces but my string is continuous.
These could be thought of as 32bit and 8bit binary numbers but they are just text in a text file (for now)!
I am brand new to programing in Python so please, I need patient details, no generalizations.
Do not assume I know anything.
Thank you,
Ralph
This should do what you want. See comprehensions for more details.
>>> s = "00000000110000000000011000000000"
>>> [s[i:i+8] for i in xrange(0, len(s), 8)]
['00000000', '11000000', '00000110', '00000000']
+1 for Robert's answer. As for 'I need to append the list to a new text file with the original string as a header':
s = "00000000110000000000011000000000"
s += '\n' + '\n'.join(s[i:i+8] for i in xrange(0, len(s), 8))
will give
'00000000110000000000011000000000\n00000000\n11000000\n00000110\n00000000'
thus putting each 'byte' on a separate line as I understood from your question...
Edit: some notes to help you understand:
A list [] (see here) contains your data, in this case, strings, between its brackets. The first item in a list is retrieved as in:
mylist[0]
in Python, a string is itself also an object, with specific methods that you can call. So '\n' (representing a carriage return) is an object of type 'string', and you can call it's method join() with your list as argument:
'\n'.join(mylist)
The elements in the list are then 'joined' together with the string '\n' in between each element. The result is no longer a list, but a string. Two strings can be added together, thus
s += '\n' + '\n'.join(mylist)
adds to s (which was already a string), the right part which is itself a 'sum' of strings.
(I hope that clears some things up?)
For reference, here are a few alternatives for splitting strings into equal length parts:
>>> import re
>>> re.findall(r'.{1,8}', s, re.S)
['00000000', '11000000', '00000110', '00000000']
>>> map(''.join, zip(*[iter(s)]*8))
['00000000', '11000000', '00000110', '00000000']
The zip method for splitting a sequence into n-length groups is documented here, but it will only work for strings whose length is evenly divisible by n (which won't be an issue for this particular question). If the string length is not evenly divisible by n you could use itertools.izip_longest(*[iter(s)]*8, fillvalue='').
Strings, Lists and Touples can be broken using the indexing operator [].
Using the : operator inside of the indexing operator you can achieve fields there.
Try something like:
x = "00000000110000000000011000000000"
part1, part2, part3, part4 = x[:8], x[8:16], x[16:24], x[24:]
you need a substring
x = 01234567
x0 = x[0:2]
x1 = x[2:4]
x2 = x[4:6]
x3 = x[6:8]
So, x0 will hold '01', x1 will hold '23', etc.

Categories

Resources