Keep only two part on element within a python list - python

I'm looking for a commande in python in order to only keep within a list the 3 first letters between content_content > con_con
here is an example:
list_exp=["Babylona_expetiendra","Ocracylus_machabrus","Ojeris_multifasciatus"]
list_exp=["Bab_exp","Ocr_mac","Oje_mul"]
Does anyone have an idea? Thank you for your help .

You can use a list-comprehension:
['_'.join(map(lambda x: x[:3], x.split('_'))) for x in list_exp]
Code:
list_exp=["Babylona_expetiendra","Ocracylus_machabrus","Ojeris_multifasciatus"]
print(['_'.join(map(lambda x: x[:3], x.split('_'))) for x in list_exp])
# ['Bab_exp', 'Ocr_mac', 'Oje_mul']

[
*map(
lambda strip:'_'.join([st[:3] for st in strip]),
[
*map(
lambda s:s.split('_'),
["Babylona_expetiendra","Ocracylus_machabrus","Ojeris_multifasciatus"]
)
]
)
]
mess explanation:
First we are splitting every string in list by '_' gigving us
[['Babylona', 'expetiendra'], ['Ocracylus', 'machabrus'], ['Ojeris', 'multifasciatus']]
Then we are getting first 3 letters using [:3] for every string inside new lists
Finnaly joining again with '_'.join()
['Bab_exp', 'Ocr_mac', 'Oje_mul']
This example using map unpacking and lamdas

You can try like this.
Before running all these, just have a quick look at the use of list comprehension & join(), split() methods defined on strings.
>>> list_exp = ["Babylona_expetiendra","Ocracylus_machabrus","Ojeris_multifasciatus"]
>>>
>>> output = ['_'.join([part[:3] for part in name.split("_")]) for name in list_exp]
>>> output
['Bab_exp', 'Ocr_mac', 'Oje_mul']
>>>

Related

Python: split this length-structured string the most elegant way

Given this string:
fsw="M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483
I'd like to convert
fsw[8:] (thus "M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483")
in a dictionary containing:
{'S16d48':'492x577', 'S10000':'505x544', 'S22a00':'506x524', 'S21300':'487x601', 'S37601':'511x574', 'S34500':'482x483'}
I managed to get the following with regexp:
>>> import re
>>> re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f]",fsw[8:])
['S16d48', 'S10000', 'S22a00', 'S21300', 'S37601', 'S34500']
>>> re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f].......",fsw[8:])
['S16d48492x577', 'S10000505x544', 'S22a00506x524', 'S21300487x601', 'S37601511x574', 'S34500482x483']
but as far as a dictionary is concerned... I failed to get any further.
Another question: in a Python dictionary it is well the whole
key-value pair (say "S16d48":"492x577") that must be unique right ?
In advance - thanks a lot.
Regards.
It seems you can alter your expression to
(?P<key>S[123][0-9a-f]{2}[0-5][0-9a-f])
(?P<value>\d+x\d+)
And then do a dict comprehension as in
import re
rx = re.compile(r'(?P<key>S[123][0-9a-f]{2}[0-5][0-9a-f])(?P<value>\d+x\d+)')
data = "M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483"
result = {m["key"]: m["value"] for m in rx.finditer(data)}
This yields
{'S16d48': '492x577', 'S10000': '505x544', 'S22a00': '506x524', 'S21300': '487x601', 'S37601': '511x574', 'S34500': '482x483'}
See a demo for the expression on regex101.com and for the code on ideone.com.
You can convert the lists you already created to a dictionary in the following way:
import re
fsw="M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483"
str_lst = re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f]",fsw[8:])
full_lst = re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f].......",fsw[8:])
str_dict = {x: y[len(x):] for x in str_lst for y in full_lst if y.startswith(x)}
This gives:
{'S16d48': '492x577',
'S10000': '505x544',
'S22a00': '506x524',
'S21300': '487x601',
'S37601': '511x574',
'S34500': '482x483'}
Not sure if I have understood what you are trying to do, but one way to obtain your dictionary from that string is
d = {}
for piece in fsw[8:].split('S')[1:]:
d["S"+piece[:5]] = piece[5:]
print(d)

How to filter a list without converting to string or loop it

I've got an object of type list and second object of type string.
I would like to filter for all values in the list-object which do not match the value of the string-object.
I have created a loop which splits the list into string and with regex found all those not matching and added these results to a new list.
This example uses hostnames "ma-tsp-a01", "ma-tsp-a02" an "ma-tsp-a03".
Currently I do further work on this new list to create a clean list of hostnames.
import re
local_hostname = 'ma-tsp-a01'
profile_files = ['/path/to/file/TSP_D01_ma-tsp-a01\n', \
'/path/to/file/TSP_D02_ma-tsp-a02\n', \
'/path/to/file/TSP_ASCS00_ma-tsp-a01\n', \
'/path/to/file/TSP_DVEBMGS03_ma-tsp-a03\n', \
'/path/to/file/TSP_DVEBMGS01_ma-tsp-a01\n']
result_list = [local_hostname]
for list_obj in profile_files:
if re.search(".*\w{3}\_\w{1,7}\d{2}\_(?!"+local_hostname+").*", list_obj):
result_list.append(list_obj.split("/")[-1].splitlines()[0].\
split("_")[-1])
print(result_list)
At the end I get the following output
['ma-tsp-a01', 'ma-tsp-a02', 'ma-tsp-a03']. This looks exactly what I am searching for. But is there a way to make this in a more pythonic way without the "for" loop?
You can create a filter object:
filtered = filter(lambda x: re.search(".*\w{3}\_\w{1,7}\d{2}\_(?!"+local_hostname+").*", x), profile_files)
Or use a generator comprehension:
filtered = (x for x in profile_files if re.search(".*\w{3}\_\w{1,7}\d{2}\_(?!"+local_hostname+").*", x))
Both behave the same

Replacing several strings in a list in a single statement

I am trying to replace the third and forth words of this list by two different words in one single statement and just can't seem to find of doing it what I tried doesn't work with the error AttributeError: 'list' object has no attribute 'replace':
friends = ["Lola", "Loic", "Rene", "Will", "Seb"]
friends.replace("Rene", "Jack").replace("Will", "Morris")
If you want to do multiple replacements probably the easiest way is to make a dictionary of what you want to replace with what:
replacements = {"Rene": "Jack", "Will": "Morris"}
and then use a list comprehension:
friends = [replacements[friend] if friend in replacements else friend for friend in friends]
Or more compactly, using dict.get() with a default value.
friends = [replacements.get(friend, friend) for friend in friends]
Another way, if you don't mind the overhead of converting the list to a pandas.Series:
import pandas as pd
friends = ["Lola", "Loic", "Rene", "Will", "Seb"]
friends = pd.Series(friends).replace(to_replace={"Rene":"Jack", "Will":"Morris"}).tolist()
print(friends)
#['Lola', 'Loic', 'Jack', 'Morris', 'Seb']
This is a not so pretty solution, but a one-liner nevertheless:
friends = list(map(lambda x: x if x != "Will" else "Morris", map(lambda x: x if x != "Rene" else "Jack", friends)))
Brief explanation:
It's a "map(lambda, list)" solution, whose output list is passed as input list to another outer "map(lambda, list)" solution.
The lambda in the inner map is for replacing "Will" with "Morris".
The lambda in the outer map is for replacing "Rene" with "Jack"

Python substitute elements inside a list

I have the following code that is filtering and printing a list. The final output is json that is in the form of name.example.com. I want to substitute that with name.sub.example.com but I'm having a hard time actually doing that. filterIP is a working bit of code that removes elements entirely and I have been trying to re-use that bit to also modify elements, it doesn't have to be handled this way.
def filterIP(fullList):
regexIP = re.compile(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$')
return filter(lambda i: not regexIP.search(i), fullList)
def filterSub(fullList2):
regexSub = re.compile(r'example\.com, sub.example.com')
return filter(lambda i: regexSub.search(i), fullList2)
groups = {key : filterSub(filterIP(list(set(items)))) for (key, items) in groups.iteritems() }
print(self.json_format_dict(groups, pretty=True))
This is what I get without filterSub
"type_1": [
"server1.example.com",
"server2.example.com"
],
This is what I get with filterSub
"type_1": [],
This is what I'm trying to get
"type_1": [
"server1.sub.example.com",
"server2.sub.example.com"
],
The statement:
regexSub = re.compile(r'example\.com, sub.example.com')
doesn't do what you think it does. It creates a compiled regular expression that matches the string "example.com" followed by a comma, a space, the string "sub", an arbitrary character, the string "example", an arbitrary character, and the string "com". It does not create any sort of substitution.
Instead, you want to write something like this, using the re.sub function to perform the substitution and using map to apply it:
def filterSub(fullList2):
regexSub = re.compile(r'example\.com')
return map(lambda i: re.sub(regexSub, "sub.example.com", i),
filter(lambda i: re.search(regexSub, i), fullList2))
If the examples are all truly as simple as those you listed, a regex is probably overkill. A simple solution would be to use string .split and .join. This would likely give better performance.
First split the url at the first period:
url = 'server1.example.com'
split_url = url.split('.', 1)
# ['server1', 'example.com']
Then you can use the sub to rejoin the url:
subbed_url = '.sub.'.join(split_url)
# 'server1.sub.example.com'
Of course you can do the split and the join at the same time
'.sub.'.join(url.split('.', 1))
Or create a simple function:
def sub_url(url):
return '.sub.'.join(url.split('.', 1))
To apply this to the list you can take several approaches.
A list comprehension:
subbed_list = [sub_url(url)
for url in url_list]
Map it:
subbed_list = map(sub_url, url_list)
Or my favorite, a generator:
gen_subbed = (sub_url(url)
for url in url_list)
The last looks like a list comprehension but gives the added benefit that you don't rebuild the entire list. It processes the elements one item at a time as the generator is iterated through. If you decide you do need the list later you can simply convert it to a list as follows:
subbed_list = list(gen_subbed)

Python Lists -Syntax for '['

I need to declare certain values in List.
Values looks like this:
["compute","controller"], ["compute"] ,["controller"]
I know the List syntax in python is
example = []
I am not sure how I will include square brackets and double quotes in the List.
Could anyone please help.
I tried the following:
cls.node = ["\["compute"\]","\["controller"\]"]
cls.node = ["[\"compute\"]","[\"controller\"]"]
Both did not work.
I think you mean list not dictionary because that is the syntax of a list:
You can simply do it using the following format '"Hello"':
cls.node = ['["compute"]','["controller"]']
cls.node = ['["compute"]','["controller"]']
Demo:
s = ['["hello"]', '["world"]']
for i in s:
print i
[OUTPUT]
["hello"]
["world"]

Categories