I have a method that takes a list of strings. Unfortunately, if the list is only one item long, Python treats this list as a string.
This post has a method for checking whether something is a string, and converting it to a list if it is:
Python: How to define a function that gets a list of strings OR a string
But this seems an incredibly redundant way of getting the item that I passed in as a list to in fact be a list. Is there a better way?
You are probably using tuples, not lists, and forgetting to add the comma to the one-item tuple literal(s). ('foo') is interpreted as simply 'foo' which would match what you are saying. However, adding a comma to one-item tuple literals will solve this. ('foo',) returns, well, ('foo',).
I'm not sure I believe you, python shouldn't behave that way, and it doesn't appear to:
>>> def foo(lst):
print type(lst)
>>> foo(['bar'])
<type 'list'>
That post was about a different thing, they wanted the ability to pass a single string or a list of strings and handle both cases as if they were lists of strings. If you're only passing in a list, always treating it as a list should be fine.
Python shouldn't do that with a list. A singleton tuple, though, has syntax different from singleton lists:
(1) == 1 # (1) is 1
[1] != 1 # [1] is a singleton list
(1,) != 1 # (1,) is a singleton tuple
You are mistaken. Python does no such transformation to lists of a single element.
Double, Triple check that you are putting the [] around the the item you are passing.
If you still can't get it working show us the code!
Related
I assumed that I defined a tuple. luckily it worked for a long time.
In one specific point it broke --> figured out that it was actually not a tuple.
In the end I expected a tuple with 1 string inside like this
("expected tuple")
Confusing, please explain
if any(key in [tuple("expect tuple"), tuple(("expect tuple"),),("expect tuple")] for key in [(("expect tuple"),)]):
print("same")
A tuple with a single element must be written like this:
("expected tuple",)
Without the , it'd be interpreted as a value surrounded by brackets, but not an actual tuple. We don't have this problem for tuples with more than one element, in those cases we don't need the trailing comma.
So i'm working on this really long program, and i want it to save an input inside of a new list, for that i have tried doing:
thing=list(input("say something")) #hello
print(thing)
#[h,e,l,l,o]
how can i arrange it to get [hello] instead?
Offhand, I'd say the easiest would be to initialize thing with an empty list and then append the user's input to it:
thing = []
thing.append(input("say something: "))
Use:
thing = [input("say something")]
In your version "hello" is treated as an iterable, which all Python strings are. A list then gets created with individual characters as items from that iterable (see docs on list()). If you want a list with the whole string as the only item, you have to do it using the square bracket syntax.
I got curious about why we can do this:
l = [1,2,3,4]
But get an error when trying this:
l = list(1,2,3,4)
Also, as most of people usually suggest, despite of passing the arguments of the latter as a tuple solves the problem, why this doesn't work either?
t = tuple(1,2,3,4)
list() and tuple() are used to convert a different type of object into a list or tuple, respectively. Any iterable will do there. The two functions are not intended to create an object from a discreet number of inputs, that's what the literal notations are for.
So if you have a fixed number of elements, each produceable with an expression, the right way to create a list is to use the [...] literal syntax. If you have a variable number of elements produced by a single iterable object, use list(). The two use-cases differ.
If list() accepted multiple arguments, then you wouldn't need to have the [...] syntax anymore; there is no point in having two different syntaxes fill the same use case.
Consider this list here:
example=[]
And another:
python=["hi","bye","hello","yes","no"]
If I decide to add one of the elements from python to example, will a duplicate of that element b created or will the variable python lose an element.
example+=[python[0]]
So would the string "hi" be duplicated or transferred to example using the aforementioned example
The string "hi" will be split into chars and assigned to example when you do example+=python[0]
So example in this case will contain ['h','i'].
Also, the list python will not lose an element.
No, there will be no "transfer". This is easy enough to check, by just printing the values after the operation.
Instead, the list example will have appended to it the elements of the first string:
>>> f = []
>>> f+= ["hi", "there"][0]
>>> f
['h', 'i']
This happens because a += b is conceptually* equivalent to a = a+b, and a+b creates a list which has all the elements of a followed by the elements of b. A string is sequence, the elements of which are strings composed of individual characters, which is why you get this behaviour.
* There are differences, notably that list + nonlist won't work.
So would the string "hi" be duplicated or transferred?
No, the string "hi" will neither be duplicated nor transferred. Rather, the length of the object to which example is bound will increase by one, and the reference example[0] will be bound to whatever object python[0] was bound to. Additionally, neither the reference python nor the object to which it is bound will be modified.
Note also, that your question has an error in the example. Where you actually said,
example += python[0]
You surely meant t say:
example += [python[0]]
A Python list stores only references to the elements. The elements (here the strings) are stored as outside objects.
Any Python assignment only copies a reference value. This way, the list is implemented as a dynamic array that stores references.
If you insert a string to a list, the source string object is not copied, only the reference to the same object is copied. The source element (here python[0]) is not removed from the list python when used on the right side of the assignment. It is only read and left untouched.
You have to do the following
example.append(python[0]
That will take the 'hi' and copy to example
Please observe the following behavior:
a = u"foo"
b = u"b\xe1r" # \xe1 is an 'a' with an accent
s = [a, b]
print a, b
print s
for x in s: print x,
The result is:
foo bár
[u'foo', u'b\xe1r']
foo bár
When I just print the two values sitting in variables a and b, I get what I expect; when I put the string values in a list and print it, I get the unwanted u"xyz" form; finally, when I print values from the list with a loop, I get the first form again. Can someone please explain this seemingly odd behavior? I know there's probably a good reason.
When you print a list, you get the repr() of each element, lists aren't really meant to be printed, so python tries to print something representative of it's structure.
If you want to format it in any particular way, either be explicit about how you want it formatted, or override it's __repr__ method.
Objects in Python have two ways to be turned into strings: roughly speaking, str() produces human readable output, and repr() produces computer-readable output. When you print something, it uses str().
But the str() of a list uses the repr() of its elements.
You get this because lists can contain any number of elements, of mixed types. In the second case, instead of printing unicode strings, you're printing the list itself - which is very different than printing the list contents.
Since the list can contain anything, you get the u'foo' syntax. If you were using non-unicode strings, you'd see the 'foo' instead of just foo, as well.