I have a list of names of apple products in random format.
like take a single product name iphone 11 pro
which can be found
Iphone 11 Pro
or iphone 11 Pro
, or anything that can be.
But i want to change this to the naming pattern how the apple gives them, eg : iPhone 11 Pro
So, I'm trying to change all of then first to title and then replacing first two characters of the string. but problem is second part is not working. Being a beginner im not able to reproduce the solution. I have read the article about regex in python. but unable to find better way to do it.
Thats how im trying..
names = ['Iphone 12', 'iphone 11 pro', 'IPad pro', 'Imac pro']
titled_names = []
updated_names = []
# first change all to title
for i in names:
i.title()
titled_names.append(i)
# replace the first two char
for i in titled_names:
i.replace('Ip', 'iP', 1)
updated_names.append(i)
print(updated_names)
But this should not supposed to work in anyway as there can some products where first char wont be Ip, like in the Imac. the end result of the names list should be like this.
names = ['iPhone 12', 'iPhone 11 Pro', 'iPad Pro', 'iMac Pro']
so how can I achieve this. first char small second capital in first letter, and rest in Title Case
CodePudding user response:
You can specify the list of desired namings.
# update to your needs
CORRECT_STRINGS = ["Apple", "iPhone", "iPad", "iMac", "MacBook", "Pro", "SE", "Max"]
names = ['Iphone 12', 'iphone 11 pro', 'IPad pro', 'Imac pro']
new_names = []
for name in names:
# convert to lower-case
correct_name = name.lower()
# replace all matching string to correct one
for correct_string in CORRECT_STRINGS:
# we want to find a lower-case string and replace it
match_string = correct_string.lower()
correct_name = correct_name.replace(match_string, correct_string)
# add correct device name to the result list
new_names.append(correct_name)
print(new_names)
>>> ['iPhone 12', 'iPhone 11 Pro', 'iPad Pro', 'iMac Pro']
Although, this approach might not always work properly if some name is a substring of another name. With Apple product this might not be the case.
UPDATE: a more elegant solution (replaces only fully matched strings)
# update to your needs
DEVICE_NAME_STRINGS = [
"Apple",
"iPhone",
"iPad",
"iMac",
"MacBook",
"Pro",
"SE",
"Max",
]
DEVICE_NAME_STRINGS_MAP = {s.lower(): s for s in DEVICE_NAME_STRINGS}
names = ['Iphone 12', 'iphone 11 pro', 'IPad pro', 'Imac pro']
def standardize_device_name(device_name: str):
"""
Example: iPhOnE 13 PrO mAx -> iPhone 13 Pro Max
"""
return " ".join(
[
DEVICE_NAME_STRINGS_MAP.get(word.lower(), word)
for word in device_name.split()
]
)
new_names = [standardize_device_name(name) for name in names]
print(new_names)
CodePudding user response:
I've done some changes and use another approach. Here I wrote function to take and return all list members with first letter in lower case. If you need second letter as well, you can add second letters index as lower as well(added in comment). This is simplest way for beginner I guess.
def first_letter_to_lower(givenList):
for i in givenList:
i = i[0].lower() i[1::]
print(i)
first_letter_to_lower(names)
OUTPUT
iphone 12
iphone 11 pro
iPad pro
imac pro
If you like to have your list back, you can add an append method in the function to return i.lowwered in "givenList"
CodePudding user response:
You'll need to append the values returned by the string methods into your lists:
names = ['Iphone 12', 'iphone 11 pro', 'IPad pro', 'Imac pro']
titled_names = []
updated_names = []
# first change all to title
for i in names:
titled_names.append(i.title())
# replace the first two char
for i in titled_names:
updated_names.append(i.replace('Ip', 'iP', 1))
print(titled_names)
print(updated_names)
Output:
['Iphone 12', 'Iphone 11 Pro', 'Ipad Pro', 'Imac Pro']
['iPhone 12', 'iPhone 11 Pro', 'iPad Pro', 'Imac Pro']
CodePudding user response:
Works like a charm!
def capitalize_nth(s, n):
"""This function will capitalize nth charcater in string"""
return s[:n].lower() s[n:].capitalize()
def edit_strings(name):
# convert given string to lowercase and strip any whitespace infront & back
name = name.lower().strip()
# split string based on first space, since we need to capitalize second character only for the first substring(product name)
# Eg: ['iphone', '12']
sub_strs = name.split(" ", 1)
return " ".join([
capitalize_nth(sub_strs[0], 1), # capitalize second character of product name
sub_strs[1].title() # capitalize first character of each word in string
])
names = ['Iphone 12', 'iphone 11 pro', 'IPad pro', 'Imac pro', 'iphone 12 pro max']
edited_names = [edit_strings(name) for name in names]
print(edited_names)
Output:
['iPhone 12', 'iPhone 11 Pro', 'iPad Pro', 'iMac Pro', 'iPhone 12 Pro Max']