python string to list (special list) - python

I'm trying to get this string into list, how can i do that pleas ?
My string :
x = "[(['xyz1'], 'COM95'), (['xyz2'], 'COM96'), (['xyz3'], 'COM97'), (['xyz4'], 'COM98'), (['xyz5'], 'COM99'), (['xyz6'], 'COM100')]"
I want to convert it to a list, so that:
print(list[0])
Output : (['xyz1'], 'COM95')

If you have this string instead of a list, that presumes it is coming from somewhere outside your control (otherwise you'd just make a proper list). If the string is coming from a source outside your program eval() is dangerous. It will gladly run any code passed to it. In this case you can use ast.liter_eval() which is safer (but make sure you understand the warning on the docs):
import ast
x = "[(['xyz1'], 'COM95'), (['xyz2'], 'COM96'), (['xyz3'], 'COM97'), (['xyz4'], 'COM98'), (['xyz5'], 'COM99'), (['xyz6'], 'COM100')]"
l = ast.literal_eval(x)
Which gives an l of:
[(['xyz1'], 'COM95'),
(['xyz2'], 'COM96'),
(['xyz3'], 'COM97'),
(['xyz4'], 'COM98'),
(['xyz5'], 'COM99'),
(['xyz6'], 'COM100')]

If the structure is uniformly a list of tuples with a one-element list of strings and an individual string, you can manually parse it using the single quote as a separator. This will give you one string value every other component of the split (which you can access using a striding subscript). You can then build the actual tuple from pairing of two values:
tuples = [([a],s) for a,s in zip(*[iter(x.split("'")[1::2])]*2)]
print(tuples[0])
(['xyz1'], 'COM95')
Note that this does not cover the case where an individual string contains a single quote that needed escaping

You mean convert list like string into list? Maybe you can use eval().
For example
a="[1,2,3,4]"
a=eval(a)
Then a become a list

to convert as list use x = eval(x)
print(list[0]) will give you an error because list is a python builtin function
you should do print(x[0]) to get what you want

Related

Why do sequence for loops don't seem to work well in Python?

I'm trying to convert every string in a list to it's lowercase format using this function:
def lower_list(strings):
for string in strings:
string = string.lower()
return strings
But this implementation is not working, however when using the range funtion and I iterate using an index:
def lower_list(strings):
for i in range(len(strings)):
strings[i] = strings[i].lower()
return strings
I do get every element on my list converted to lowercase:
> print(lower_list(mylist))
['oh brother where art thou', 'hello dolly', 'monsters inc', 'fargo']
But with the first implementation I get the original list with Uppercase values, am I missing something important in how the for loop works?
In the first case, all you are doing is storing the lowercase value in a variable, but the list is untouched.
In the second case, you are actually updating the value in the list at that index.
You can also use a lambda function here:
def lower_list(strings):
return list(map(lambda x: x.replace(x, x.lower()), strings))
List comprehension is the easiest and the best:
def lower_list(strings):
return [string.lower() for string in strings]
The reason the first one does not work is that it is not actually modifying the value inside of the list, rather it is just affecting a copy of the value in the list. When you use the index-based function, it modifies the list itself.
def lower_list(strings):
for string in strings:
index_of_string = strings.index(string)
string = string.lower()
strings[index_of_string] = string
return strings
If you want the first one to work, maybe you can try something like that, but thats a bad way of doing it, just showing it as an example so maybe you'll understand better. You need the index of that string so you can replace it in the list. In your first attempt, you do not replace anything in the list.

How to split a string with an integer into two variables?

For example, is it possible to convert the input
x = 10hr
into something like
y = 10
z = hr
I considering slicing, but the individual parts of the string will never be of a fixed length -- for example, the base string could also be something like 365d or 9minutes.
I'm aware of split() and re.match which can separate items into a list/group based on delimitation. But I'm curious what the shortest way to split a string containing a string and an integer into two separate variables is, without having to reassign the elements of the list.
You could use list comprehension and join it as a string
x='10hr'
digits="".join([i for i in x if not i.isalpha()])
letters="".join([i for i in x if i.isalpha()])
You don't need some fancy function or regex for your use case
x = '10hr'
i=0
while x[i].isdigit():
i+=1
The solution assumes that the string is going to be in format you have mentioned: 10hr, 365d, 9minutes, etc..
Above loop will get you the first index value i for the string part
>>i
2
>>x[:i]
'10'
>>x[i:]
'hr'

How to Remove single Inverted comma from array in python?

I have the following array:
a =['1','2']
I want to convert this array into the below format :
a=[1,2]
How can I do that?
You can do it like that. You change each element of a (which are strings) in an integer.
a=[int(x) for x in a]
This single inverted comma you are talking about is the difference between str and int. This is pretty basic python stuff.
A string is a characters, displayed with the inverted comma's around it. 'Hello' is a string, but '1' can be a string too.
In you case ['1','2'] is a list of strings, and [1,2] is a list of numbers.
To convert a string to an int, you can do what is called casting. This is converting one type to another (They have to be compatible though.) Casting 'hello' to a number doesn't make sense and won't work.
Casting '1' to a number is possible by calling int('1') which will result in 1
In your case you can cast all elements in you list by calling a = [int(x) for x in a].
For more info on types see this article.
For information on list comprehensions (What I used to change your list) see this article.

Pymongo Regex match with list

I have a list of distinct strings.
lst = ['.\*123.\*','.\*252.\*','.\*812.\*','.\*135.\*']
I want to perform an aggregation operation such that my $match looks like the following:
{"$match":{"Var":{"$in":lst}}}
The var field in MongoDb records is a string containing numbers:
e.g. "abc123", "haaofalfa812", etc. I want to match this Var to a regular expression. If the variables in the lst were less, i could've done this...
{"$match":{"Var":{"$in":[re.compile('.*123.*'),re.compile('.*252.*'),re.compile('.*812.*')]}}}
But since it is a lst already initialized and contains a lot of elements, what should I do?
I tried the following but this doesn't work too...
{"$match":{"Var":{"$in":[re.compile(x for x in lst)]}}}
I get the following error for obvious reasons.
TypeError: first argument must be string or compiled pattern
Your list comprehension is wrong. I reckon what you wanted to do is this:
[re.compile(x) for x in lst]
That TypeError comes from trying to pass generator(x for x in lst statement) to re.compile()

Add string to another string

I currently encountered a problem:
I want to handle adding strings to other strings very efficiently, so I looked up many methods and techniques, and I figured the "fastest" method.
But I quite can not understand how it actually works:
def method6():
return ''.join([`num` for num in xrange(loop_count)])
From source (Method 6)
Especially the ([`num` for num in xrange(loop_count)]) confused me totally.
it's a list comprehension, that uses backticks for repr conversion. Don't do this. Backticks are deprecated and removed in py3k and more efficient and pythonic way is not to build intermediate list at all, but to use generator expression:
''.join(str(num) for num in xrange(loop_count)) # use range in py3k
xrange() is a faster (written in C) version of range().
Backtick notation -- num, coerces a variable to a string, and is the same as str(num).
[x for x in y] is called a list comprehension, and is basically an one-liner for loop that returns a list as its result. So all together, your code's semantically equivalent to the following, but faster, because list comprehensions and xrange are faster than for loops and range:
z = []
for i in range(loop_count):
z.append(str(i))
return "".join(z)
That bit in the brackets is a list comprehension, arguably one of the most powerful elements of Python. It produces a list from iteration. You may want to look up its documentation. The use of backticks to convert num to a string is not suggestible - try str(num) or some such instead.
join() is a method of the string class. It takes a list of strings and return a single string consisting of each component string separated by "self" (aka the calling string). The trick here is that join() is being called directly from the string literal '', which is allowed in Python. What this code will to is produce a string consisting of the string form of each element of xrange(loop_count) with no separation.
First of all: while this code is still correct in the 2.x series of Python, it a bit confusing and can be written differently:
def method6a():
return ''.join(str(num) for num in xrange(loop_count))
In Python 2.x, the backticks can be used instead of the repr function. The expression within the square brackets [] is a list comprehension. In case you are new to list comprehensions: they work like a combination of a loop and a list append-statement, only that you don't have to invent a name for a variable:
Those two are equivalent:
a = [repr(num) for num in xrange(loop_count)]
# <=>
a = []
for num in xrange(loop_count):
a.append(repr(num))
As a result, the list comprehension will contain a list of all numbers from 0 to loop_count (exclusively).
Finally, string.join(iterable) will use the contents of string concatenate all of the strings in iterable, using string as the seperator between each element. If you use the empty string as the seperator, then all elements are concatenated without anything between them - this is exactly what you wanted: a concatenation of all of the numbers from 0 to loop_count.
As for my modifications:
I used str instead of repr because the result is the same for all ints and it is easier to read.
I am using a generator expression instead of a list comprehension because the list built by the list comprehension is unnecessary and gets garbage collected anyway. Generator expressions are iterable, but they don't need to store all elements of the list. Of course, if you already have a list of strings, then simply pass the list to the join.
Generally, the ''.join(iterable) idiom is well understood by most Python programmers to mean "string concatenation of any list of strings", so understandability shouldn't be an issue.

Categories