Related
I tried to use input (Py3) /raw_input() (Py2) to get a list of numbers, however with the code
numbers = input()
print(len(numbers))
the input [1,2,3] and 1 2 3 gives a result of 7 and 5 respectively – it seems to interpret the input as if it were a string. Is there any direct way to make a list out of it? Maybe I could use re.findall to extract the integers, but if possible, I would prefer to use a more Pythonic solution.
In Python 3.x, use this.
a = [int(x) for x in input().split()]
Example
>>> a = [int(x) for x in input().split()]
3 4 5
>>> a
[3, 4, 5]
>>>
It is much easier to parse a list of numbers separated by spaces rather than trying to parse Python syntax:
Python 3:
s = input()
numbers = list(map(int, s.split()))
Python 2:
s = raw_input()
numbers = map(int, s.split())
Using Python-like syntax
The standard library provides ast.literal_eval, which can evaluate certain strings as though they were Python code. This does not create a security risk, but it can still result in crashes and a wide variety of exceptions.
For example: on my machine ast.literal_eval('['*1000 + ']'*1000) will raise MemoryError, even though the input is only two kilobytes of text.
As explained in the documentation:
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.
(The documentation is slightly inaccurate. ast.literal_eval also supports addition and subtraction of numbers - but not any other operators - so that it can support complex numbers.)
This is sufficient for reading and parsing a list of integers formatted like Python code (e.g. if the input is [1, 2, 3]. For example:
>>> import ast
>>> ast.literal_eval(input("Give me a list: "))
Give me a list: [1,2,3]
[1, 2, 3]
Do not ever use eval for input that could possibly ever come, in whole or in part, from outside the program. It is a critical security risk that enables the creator of that input to run arbitrary code.
It cannot be properly sandboxed without significant expertise and massive restrictions - at which point it is obviously much easier to just use ast.literal_eval. This is increasingly important in our Web-connected world.
In Python 2.x, raw_input is equivalent to Python 3.x input; 2.x input() is equivalent to eval(raw_input()). Python 2.x thus exposed a critical security risk in its built-in, designed-to-be-beginner-friedly functionality, and did so for many years. It also has not been officially supported since Jan 1, 2020. It is approximately as outdated as Windows 7.
Do not use Python 2.x unless you absolutely have to; if you do, do not use the built-in input.
Using your own syntax
Of course, it is clearly possible to parse the input according to custom rules. For example, if we want to read a list of integers, one simple format is to expect the integer values separated by whitespace.
To interpret that, we need to:
Split the string at the whitespace, which will give us a list
Convert strings into integers, and apply that logic to each string in the list.
All of those tasks are covered by the common linked duplicates; the resulting code is shown in the top answer here.
Using other syntaxes
Rather than inventing a format for the input, we could expect input in some other existing, standard format - such as JSON, CSV etc. The standard library includes tools to parse those two. However, it's generally not very user-friendly to expect people to type such input by hand at a prompt. Normally this kind of input will be read from a file instead.
Verifying input
ast.literal_eval will also read and parse many things that aren't a list of integers; so subsequent code that expects a list of integers will still need to verify the input.
Aside from that, if the input isn't formatted as expected, generally some kind of exception will be thrown. Generally you will want to check for this, in order to repeat the prompt. Please see Asking the user for input until they give a valid response.
You can use .split()
numbers = raw_input().split(",")
print len(numbers)
This will still give you strings, but it will be a list of strings.
If you need to map them to a type, use list comprehension:
numbers = [int(n, 10) for n in raw_input().split(",")]
print len(numbers)
If you want to be able to enter in any Python type and have it mapped automatically and you trust your users IMPLICITLY then you can use eval
Another way could be to use the for-loop for this one.
Let's say you want user to input 10 numbers into a list named "memo"
memo=[]
for i in range (10):
x=int(input("enter no. \n"))
memo.insert(i,x)
i+=1
print(memo)
you can pass a string representation of the list to json:
import json
str_list = raw_input("Enter in a list: ")
my_list = json.loads(str_list)
user enters in the list as you would in python: [2, 34, 5.6, 90]
Answer is trivial. try this.
x=input()
Suppose that [1,3,5,'aA','8as'] are given as the inputs
print len(x)
this gives an answer of 5
print x[3]
this gives 'aA'
a=[]
b=int(input())
for i in range(b):
c=int(input())
a.append(c)
The above code snippets is easy method to get values from the user.
Get a list of number as input from the user.
This can be done by using list in python.
L=list(map(int,input(),split()))
Here L indicates list, map is used to map input with the position, int specifies the datatype of the user input which is in integer datatype, and split() is used to split the number based on space.
.
I think if you do it without the split() as mentioned in the first answer. It will work for all the values without spaces. So you don't have to give spaces as in the first answer which is more convenient I guess.
a = [int(x) for x in input()]
a
Here is my ouput:
11111
[1, 1, 1, 1, 1]
try this one ,
n=int(raw_input("Enter length of the list"))
l1=[]
for i in range(n):
a=raw_input()
if(a.isdigit()):
l1.insert(i,float(a)) #statement1
else:
l1.insert(i,a) #statement2
If the element of the list is just a number the statement 1 will get executed and if it is a string then statement 2 will be executed. In the end you will have an list l1 as you needed.
I tried to use input (Py3) /raw_input() (Py2) to get a list of numbers, however with the code
numbers = input()
print(len(numbers))
the input [1,2,3] and 1 2 3 gives a result of 7 and 5 respectively – it seems to interpret the input as if it were a string. Is there any direct way to make a list out of it? Maybe I could use re.findall to extract the integers, but if possible, I would prefer to use a more Pythonic solution.
In Python 3.x, use this.
a = [int(x) for x in input().split()]
Example
>>> a = [int(x) for x in input().split()]
3 4 5
>>> a
[3, 4, 5]
>>>
It is much easier to parse a list of numbers separated by spaces rather than trying to parse Python syntax:
Python 3:
s = input()
numbers = list(map(int, s.split()))
Python 2:
s = raw_input()
numbers = map(int, s.split())
Using Python-like syntax
The standard library provides ast.literal_eval, which can evaluate certain strings as though they were Python code. This does not create a security risk, but it can still result in crashes and a wide variety of exceptions.
For example: on my machine ast.literal_eval('['*1000 + ']'*1000) will raise MemoryError, even though the input is only two kilobytes of text.
As explained in the documentation:
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.
(The documentation is slightly inaccurate. ast.literal_eval also supports addition and subtraction of numbers - but not any other operators - so that it can support complex numbers.)
This is sufficient for reading and parsing a list of integers formatted like Python code (e.g. if the input is [1, 2, 3]. For example:
>>> import ast
>>> ast.literal_eval(input("Give me a list: "))
Give me a list: [1,2,3]
[1, 2, 3]
Do not ever use eval for input that could possibly ever come, in whole or in part, from outside the program. It is a critical security risk that enables the creator of that input to run arbitrary code.
It cannot be properly sandboxed without significant expertise and massive restrictions - at which point it is obviously much easier to just use ast.literal_eval. This is increasingly important in our Web-connected world.
In Python 2.x, raw_input is equivalent to Python 3.x input; 2.x input() is equivalent to eval(raw_input()). Python 2.x thus exposed a critical security risk in its built-in, designed-to-be-beginner-friedly functionality, and did so for many years. It also has not been officially supported since Jan 1, 2020. It is approximately as outdated as Windows 7.
Do not use Python 2.x unless you absolutely have to; if you do, do not use the built-in input.
Using your own syntax
Of course, it is clearly possible to parse the input according to custom rules. For example, if we want to read a list of integers, one simple format is to expect the integer values separated by whitespace.
To interpret that, we need to:
Split the string at the whitespace, which will give us a list
Convert strings into integers, and apply that logic to each string in the list.
All of those tasks are covered by the common linked duplicates; the resulting code is shown in the top answer here.
Using other syntaxes
Rather than inventing a format for the input, we could expect input in some other existing, standard format - such as JSON, CSV etc. The standard library includes tools to parse those two. However, it's generally not very user-friendly to expect people to type such input by hand at a prompt. Normally this kind of input will be read from a file instead.
Verifying input
ast.literal_eval will also read and parse many things that aren't a list of integers; so subsequent code that expects a list of integers will still need to verify the input.
Aside from that, if the input isn't formatted as expected, generally some kind of exception will be thrown. Generally you will want to check for this, in order to repeat the prompt. Please see Asking the user for input until they give a valid response.
You can use .split()
numbers = raw_input().split(",")
print len(numbers)
This will still give you strings, but it will be a list of strings.
If you need to map them to a type, use list comprehension:
numbers = [int(n, 10) for n in raw_input().split(",")]
print len(numbers)
If you want to be able to enter in any Python type and have it mapped automatically and you trust your users IMPLICITLY then you can use eval
Another way could be to use the for-loop for this one.
Let's say you want user to input 10 numbers into a list named "memo"
memo=[]
for i in range (10):
x=int(input("enter no. \n"))
memo.insert(i,x)
i+=1
print(memo)
you can pass a string representation of the list to json:
import json
str_list = raw_input("Enter in a list: ")
my_list = json.loads(str_list)
user enters in the list as you would in python: [2, 34, 5.6, 90]
Answer is trivial. try this.
x=input()
Suppose that [1,3,5,'aA','8as'] are given as the inputs
print len(x)
this gives an answer of 5
print x[3]
this gives 'aA'
a=[]
b=int(input())
for i in range(b):
c=int(input())
a.append(c)
The above code snippets is easy method to get values from the user.
Get a list of number as input from the user.
This can be done by using list in python.
L=list(map(int,input(),split()))
Here L indicates list, map is used to map input with the position, int specifies the datatype of the user input which is in integer datatype, and split() is used to split the number based on space.
.
I think if you do it without the split() as mentioned in the first answer. It will work for all the values without spaces. So you don't have to give spaces as in the first answer which is more convenient I guess.
a = [int(x) for x in input()]
a
Here is my ouput:
11111
[1, 1, 1, 1, 1]
try this one ,
n=int(raw_input("Enter length of the list"))
l1=[]
for i in range(n):
a=raw_input()
if(a.isdigit()):
l1.insert(i,float(a)) #statement1
else:
l1.insert(i,a) #statement2
If the element of the list is just a number the statement 1 will get executed and if it is a string then statement 2 will be executed. In the end you will have an list l1 as you needed.
I've recently been practicing using map() in Python 3.5.2, and when I tried to run the module it said the comma separating the function and the iterable was a SyntaxError. Here's the code:
eng_swe = {"merry":"god", "christmas":"jul", "and":"och", "happy":"gott",
"new":"nytt", "year":"år"}
def map_translate(l):
"""Translates English words into Swedish using the dictionary above."""
return list(map(lambda x: eng_swe[x] if x in eng_swe.keys(), l))
I noticed that if I eliminate the conditional statement like this:
return list(map(lambda x: eng_swe[x], l))
it works fine, but it sacrifices the ability to avoid attempting to add items to the list that aren't in the dictionary. Interestingly enough, there also weren't any problems when I tried using a conditional statement with reduce(), as shown here:
from functools import reduce
def reduce_max_in_list(l):
"""Returns maximum integer in list using the 'reduce' function."""
return reduce(lambda x, y: x if x > y else y, l)
Yes, I know I could do the exact same thing more cleanly and easily with a list comprehension, but I consider it worth my time to at least learn how to use map() correctly, even if I end up never using it again.
You're getting the SyntaxError because you're using a conditional expression without supplying the else clause which is mandatory.
The grammar for conditional expressions (i.e if statements in an expression form) always includes an else clause:
conditional_expression ::= or_test ["if" or_test "else" expression]
^^
In your reduce example you do supply it and, as a result, no errors are being raised.
In your first example, you don't specify what should be returned if the condition isn't true. Since python can't yield nothing from an expression, that is a syntax error. e.g:
a if b # SyntaxError.
a if b else c # Ok.
You might argue that it could be useful to implicitly yield None in this case, but I doubt that a proposal of that sort would get any traction within the community... (I wouldn't vote for it ;-)
While the others' explanations of why your code is causing a SyntaxError are completely accurate, the goal of my answer is to aid you in your goal "to at least learn how to use map() correctly."
Your use of map in this context does not make much sense. As you noted in your answer it would be much cleaner if you used a list comprehension:
[eng_swe[x] for x in l if x in eng_swe]
As you can see, this looks awfully similar to your map expression, minus some of the convolution. Generally, this is a sign that you're using map incorrectly. map(lambda... is pretty much a code smell. (Note that I am saying this as an ardent supporter of the use of map in Python. I know many people think it should never be used, but I am not one of those people, as long as it is used properly.)
So, you might be wondering, what is an example of a good time to use map? Well, one use case I can think of off the top of my head is converting a list of strs to ints. For example, if I am reading a table of data stored in a file, I might do:
with open('my_file.txt', 'r') as f:
data = [map(int, line.split(' ')) for line in f]
Which would leave me with a 2d-array of ints, perfect for further manipulation or analysis. What makes this a better use of map than your code is that it uses a built-in function. I am not writing a lambda expressly to be used by map (as this is a sign that you should use a list comprehension).
Getting back to your code, however... if you want to write your code functionally, you should really be using filter, which is just as important to know as map.
map(lambda x: eng_swe[x], filter(lambda x: eng_swe.get(x), l))
Note that I was unable to get rid of the map(lambda... code smell in my version, but at least I broke it down into smaller parts. The filter finds the words that can be translated and the map performs the actual translation. (Still, in this case, a list comprehension is probably better.) I hope that this explanation helps you more than it confuses you in your quest to write Python code functionally.
I'm new to python and this is just to automate something on my PC. I want to concatenate all the items in a list. The problem is that
''.join(list)
won't work as it isn't a list of strings.
This site http://www.skymind.com/~ocrow/python_string/ says the most efficient way to do it is
''.join([`num` for num in xrange(loop_count)])
but that isn't valid python...
Can someone explain the correct syntax for including this sort of loop in a string.join()?
You need to turn everything in the list into strings, using the str() constructor:
''.join(str(elem) for elem in lst)
Note that it's generally not a good idea to use list for a variable name, it'll shadow the built-in list constructor.
I've used a generator expression there to apply the str() constructor on each and every element in the list. An alternative method is to use the map() function:
''.join(map(str, lst))
The backticks in your example are another spelling of calling repr() on a value, which is subtly different from str(); you probably want the latter. Because it violates the Python principle of "There should be one-- and preferably only one --obvious way to do it.", the backticks syntax has been removed from Python 3.
Here is another way (discussion is about Python 2.x):
''.join(map(str, my_list))
This solution will have the fastest performance and it looks nice and simple imo. Using a generator won't be more efficient. In fact this will be more efficient, as ''.join has to allocate the exact amount of memory for the string based on the length of the elements so it will need to consume the whole generator before creating the string anyway.
Note that `` has been removed in Python 3 and it's not good practice to use it anymore, be more explicit by using str() if you have to eg. str(num).
just use this, no need of [] and use str(num):
''.join(str(num) for num in xrange(loop_count))
for list just replace xrange(loop_count) with the list name.
example:
>>> ''.join(str(num) for num in xrange(10)) #use range() in python 3.x
'0123456789'
If your Python is too old for "list comprehensions" (the odd [x for x in ...] syntax), use map():
''.join(map(str, list))
I am tryiing to port some python code to ruby, and I am doing pretty well, using equivelent ruby functions, even removing / altering some to use ruby features more.
However at a core point I need to get slices from an array
in python the following works fine:
output=["Apple","Orange","Pear"]
team_slices=[(0,1),(1,2),(2,3)]
for start,end in team_slices:
print output[start:end]
Will output as expected:
['Apple']
['Orange']
['Pear']
Whereas the ruby code:
output=["Apple","Orange","Pear"]
team_slices=[[0,1],[1,2],[2,3]]
team_slices.each do |start,ending|
print output[start..ending]
end
Will output:
["Apple","Orange"]
["Orange","Pear"]
["Pear"]
Is there any way to do the slicing more equivalent to python? I know I am likely missing somethign simple here
Seems like python's ranges exclude the end value, so just use the ... variant in ruby:
output=["Apple","Orange","Pear"]
team_slices=[[0,1],[1,2],[2,3]]
team_slices.each do |start, last|
print output[start...last]
end
PS: In ruby you should use 2 spaces for indentation, if you want to stick to conventions ;)
EDIT| Had to rename end to last due to ruby using it as a syntactical keyword.