Iterate through a list using re.sub() - python

I am trying to replace the valuse in a list with the long format name.
value_list = ['Gi1/0/8', 'Gi1/0/31', 'Gi1/0/32', 'Gi1/0/33', 'Gi1/0/34', 'Gi1/0/23', 'Gi1/0/27']
I am running the following script:
for value in value_list:
value = re.sub(r'Gi', 'GigabitEthernet', value)
print value
print value_list
This is my out put:
GigabitEthernet1/0/8
GigabitEthernet1/0/31
GigabitEthernet1/0/32
GigabitEthernet1/0/33
GigabitEthernet1/0/34
GigabitEthernet1/0/23
GigabitEthernet1/0/27
I just need to change the values in the list, it seems doing it all wrong. Can anyone help me do this in an efficient manner so i dont need to create another list from the individual outputs??

Then use list comprehension instead:
print([re.sub(r'Gi', 'GigabitEthernet', value) for value in value_list])
Output:
['GigabitEthernet1/0/8', 'GigabitEthernet1/0/31', 'GigabitEthernet1/0/32', 'GigabitEthernet1/0/33', 'GigabitEthernet1/0/34', 'GigabitEthernet1/0/23', 'GigabitEthernet1/0/27']

This code updates existing list:
value_list = ['Gi1/0/8', 'Gi1/0/31', 'Gi1/0/32', 'Gi1/0/33', 'Gi1/0/34', 'Gi1/0/23', 'Gi1/0/27']
for i in range(len(value_list)):
value_list[i] = re.sub(r'Gi', 'GigabitEthernet', value_list[i])
print value_list
# ['GigabitEthernet1/0/8', 'GigabitEthernet1/0/31', 'GigabitEthernet1/0/32', 'GigabitEthernet1/0/33', 'GigabitEthernet1/0/34', 'GigabitEthernet1/0/23', 'GigabitEthernet1/0/27']

Using map
Ex:
import re
value_list = ['Gi1/0/8', 'Gi1/0/31', 'Gi1/0/32', 'Gi1/0/33', 'Gi1/0/34', 'Gi1/0/23', 'Gi1/0/27']
value_list = list(map(lambda value: re.sub(r'Gi', 'GigabitEthernet', value), value_list))
print(value_list)
Output:
['GigabitEthernet1/0/8', 'GigabitEthernet1/0/31', 'GigabitEthernet1/0/32', 'GigabitEthernet1/0/33', 'GigabitEthernet1/0/34', 'GigabitEthernet1/0/23', 'GigabitEthernet1/0/27']

To change the list "in-place" you need to set each item in the list to the new value. Just doing value = re.sub(r'Gi', 'GigabitEthernet', item) doesn't change the value stored in the list.
This code changes the values in the list:
>>> value_list = ['Gi1/0/8', 'Gi1/0/31', 'Gi1/0/32', 'Gi1/0/33', 'Gi1/0/34', 'Gi1/0/23', 'Gi1/0/27']
>>> for idx, item in enumerate(value_list):
... value_list[idx] = re.sub(r'Gi', 'GigabitEthernet', item)
...
>>> value_list
['GigabitEthernet1/0/8', 'GigabitEthernet1/0/31', 'GigabitEthernet1/0/32', 'GigabitEthernet1/0/33', 'GigabitEthernet1/0/34', 'GigabitEthernet1/0/23', 'GigabitEthernet1/0/27']
The enumerate function generates the list indexes for you, so you can iterate over your list pythonically (for item in mylist) rather than indexing directly (for i in range(len(mylist))) which produces less readable code.

Related

Remove file name duplicates in a list

I have a list l:
l = ['Abc.xlsx', 'Wqe.csv', 'Abc.csv', 'Xyz.xlsx']
In this list, I need to remove duplicates without considering the extension. The expected output is below.
l = ['Wqe.csv', 'Abc.csv', 'Xyz.xlsx']
I tried:
l = list(set(x.split('.')[0] for x in l))
But getting only unique filenames without extension
How could I achieve it?
You can use a dictionary comprehension that uses the name part as key and the full file name as the value, exploiting the fact that dict keys must be unique:
>>> list({x.split(".")[0]: x for x in l}.values())
['Abc.csv', 'Wqe.csv', 'Xyz.xlsx']
If the file names can be in more sophisticated formats (such as with directory names, or in the foo.bar.xls format) you should use os.path.splitext:
>>> import os
>>> list({os.path.splitext(x)[0]: x for x in l}.values())
['Abc.csv', 'Wqe.csv', 'Xyz.xlsx']
If the order of the end result doesn't matter, we could split each item on the period. We'll regard the first item in the list as the key and then keep the item if the key is unique.
oldList = l
setKeys = set()
l = []
for item in oldList:
itemKey = item.split(".")[0]
if itemKey in setKeys:
pass
else:
setKeys.add(itemKey)
l.append(item)
Try this
l = ['Abc.xlsx', 'Wqe.csv', 'Abc.csv', 'Xyz.xlsx']
for x in l:
name = x.split('.')[0]
find = 0
for index,d in enumerate(l, start=0):
txt = d.split('.')[0]
if name == txt:
find += 1
if find > 1:
l.pop(index)
print(l)
#Selcuk Definitely the best solution, unfortunately I don't have enough reputation to vote you answer.
But I would rather use el[:el.rfind('.')] as my dictionary key than os.path.splitext(x)[0] in order to handle the case where we have sophisticated formats in the name. that will give something like this:
list({x[:x.rfind('.')]: x for x in l}.values())

Converting a list with multiple values into a dictionary

I have the following list and am wanting to convert it into a dictionary where the 4 digit value at the start of each item becomes the id.
['3574,A+,2021-03-24', '3575,O+,2021-04-03', '3576,AB-,2021-04-09', '3580,AB+,2021-04-27', '3589,A+,2021-05-08', '3590,B-,2021-05-11']
I have tried many different methods but it doesn't seem to work.
You can use str.split, map and dictionary comprehension
# data holds the list you have provided
{splitted[0]:splitted[1:] for splitted in map(lambda item:item.split(','), data)}
OUTPUT:
Out[35]:
{'3574': ['A+', '2021-03-24'],
'3575': ['O+', '2021-04-03'],
'3576': ['AB-', '2021-04-09'],
'3580': ['AB+', '2021-04-27'],
'3589': ['A+', '2021-05-08'],
'3590': ['B-', '2021-05-11']}
You can use dictionary comprehension with str.split:
lst = [
"3574,A+,2021-03-24",
"3575,O+,2021-04-03",
"3576,AB-,2021-04-09",
"3580,AB+,2021-04-27",
"3589,A+,2021-05-08",
"3590,B-,2021-05-11",
]
out = {int(v.split(",")[0]): v.split(",")[1:] for v in lst}
print(out)
Prints:
{
3574: ["A+", "2021-03-24"],
3575: ["O+", "2021-04-03"],
3576: ["AB-", "2021-04-09"],
3580: ["AB+", "2021-04-27"],
3589: ["A+", "2021-05-08"],
3590: ["B-", "2021-05-11"],
}
Here is the code to do what I believe you asked for. I have also added comments in the code for a bit more clarification.
my_list = ['3574,A+,2021-03-24',
'3575,O+,2021-04-03',
'3576,AB-,2021-04-09',
'3580,AB+,2021-04-27',
'3589,A+,2021-05-08',
'3590,B-,2021-05-11']#your list
my_dict = {}#The dictionary you want to put the list into
print("Your list:", my_list, "\n")
for item in my_list:#cycles through every item in your list
ID, value = item.split(",", 1)#Splits the item in your list only once (when it sees the first comma)
print(ID + ": " + value)
my_dict[ID] = value#Add the ID and value to your dictionary
print("\n" + "Your desired dictionary:", my_dict)
Which outputs this:
Your list: ['3574,A+,2021-03-24', '3575,O+,2021-04-03', '3576,AB-,2021-04-09', '3580,AB+,2021-04-27', '3589,A+,2021-05-08', '3590,B-,2021-05-11']
3574: A+,2021-03-24
3575: O+,2021-04-03
3576: AB-,2021-04-09
3580: AB+,2021-04-27
3589: A+,2021-05-08
3590: B-,2021-05-11
Your desired dictionary: {'3574': 'A+,2021-03-24', '3575': 'O+,2021-04-03', '3576': 'AB-,2021-04-09', '3580': 'AB+,2021-04-27', '3589': 'A+,2021-05-08', '3590': 'B-,2021-05-11'}
Enjoy!
TRY:
result = dict(i.split(',', 1) for i in lst)
OUTPUT:
{'3574': 'A+,2021-03-24',
'3575': 'O+,2021-04-03',
'3576': 'AB-,2021-04-09',
'3580': 'AB+,2021-04-27',
'3589': 'A+,2021-05-08',
'3590': 'B-,2021-05-11'}

How can you erase a particular value in the list?

How can you erase a particular value in the list?
The value of the list exists.
review_list = ["14hour","16hour","20hour","24hour","8hour","4hour","2hour","hello","jae12"]
If you look at the list value,
Only numeric values change before int(1-24)hour.
How can you remove int (1-24)hour and output the remaining values?
OUTPUT
review_list = "hello","jae12"]
Based on your expected output, you want to remove elements which contain "hour" in the value
review_list = ["14hour","16hour","20hour","24hour","8hour","4hour","2hour","hello","jae12"]
review_filtered = [x for x in review_list if "hour" not in x]
Output
["hello", "jae12"]
review_list = list(filter(lambda item: not item.endswith("hour"), review_list))
or
import re
review_list = list(filter(lambda item: not re.match('^[0-9]+hour$',item), review_list))

How we can read first element of key from List?

I am new to python. How can I get the first value from list? When I am printing x[0] I am getting EmpId:244.
txt = "EmpId:244|Name:'Adi'|contact_no:1234567890|product_code:538365085|date:2020-04-06|fileName:Report_BGDE_16-Apr-2020|code:ABC|resubmitted:Y|file_format:CSV"
x = txt.split("|")
print(x[0])
I need to return only EmpId. Any solution will help me. Thanks
You need to split once more on : char.
txt = "EmpId:244|Name:'Adi'|contact_no:1234567890|product_code:538365085|date:2020-04-06|fileName:Report_BGDE_16-Apr-2020|code:ABC|resubmitted:Y|file_format:CSV"
object = txt.split("|")[0]
key_value = object.split(':')
key = key_value[0] # EmpId
value = key_value[1] #244
You could use
txt = "EmpId:244|Name:'Adi'|contact_no:1234567890|product_code:538365085|date:2020-04-06|fileName:Report_BGDE_16-Apr-2020|code:ABC|resubmitted:Y|file_format:CSV"
values = (item.split(":") for item in txt.split("|"))
key, value = next(values)
print(value)
You can convert to dict:
my_dict = {k : v for k, v in [item.split(':') for item in txt.split('|')]}
print(my_dict['EmpId'])
'244'
This could also neatly help in case you want more fields other than EmpId later:
dict(item.split(":") for item in txt.split("|"))
On extending Mr. #Jan answer, it is much more easy to store the data into a dictionary than a list or tuple or generator
d = {item.split(":")[0]:item.split(":")[1] for item in txt.split("|")}
Then, any required field can be retrieved using the key as in
d['EmpId'] will give 244
d['product_code'] gives 538365085

How do I get next element from list after search string match in python

Hi Friends I have a list where I'm searching for string and along with searched string I want to get next element of list item. Below is sample code
>>> contents = ['apple','fruit','vegi','leafy']
>>> info = [data for data in contents if 'fruit' in data]
>>> print(info)
['fruit']
I want to have output as
fruit
vegi
What about:
def find_adjacents(value, items):
i = items.index(value)
return items[i:i+2]
You'll get a ValueError exception for free if the value is not in items :)
I might think of itertools...
>>> import itertools
>>> contents = ['apple','fruit','vegi','leafy']
>>> icontents = iter(contents)
>>> iterable = itertools.dropwhile(lambda x: 'fruit' not in x, icontents)
>>> next(iterable)
'fruit'
>>> next(iterable)
'vegi'
Note that if you really know that you have an exact match (e.g. 'fruit' == data instead of 'fruit' in data), this becomes easier:
>>> ix = contents.index('fruit')
>>> contents[ix: ix+2]
['fruit', 'vegi']
In both of these cases, you'll need to specify what should happen if no matching element is found.
One way to do that is to iterate over the list zipped with itself.
Calling zip(contents, contents[1:]), allows the data variable to take on these values during the loop:
('apple', 'fruit')
('fruit', 'vegi')
('vegi', 'leafy')
in that order. Thus, when "fruit" is matched, data has the value ('fruit', 'vegi').
Consider this program:
contents = ['apple','fruit','vegi','leafy']
info = [data for data in zip(contents,contents[1:]) if 'fruit' == data[0]]
print(info)
We compare "fruit" to data[0], which will match when data is ('fruit', 'vegi').
This straightforward imperative approach worked for me:
contents = ['apple', 'fruit', 'vegi', 'leafy']
result = '<no match or no successor>'
search_term = 'fruit'
for i in range(len(contents)-1):
if contents[i] == search_term:
result = contents[i+1]
print result
Note that you don't specify what the behavior should be for 1) not finding the search term, or 2) finding a match at the end of the list.

Categories

Resources