1

The aim is to create unique device names. If a device already exists with a similar name, append an integer incremented by 1 for each occurrence.

This is my approach:

def deviceNamesSystem(devicenames):
    if not devicenames:
        return None
    unique_device_names = []
    devices = Counter(devicenames) #Group devices by names
    for device_name,occurence in devices.items():
        for item_integer in range(occurence):
            #Append integer if device name already in list of unique devices
            if item_integer == 0:
                unique_device_names.append(device_name)
            else:
                unique_device_names.append(f"{device_name}{item_integer}")

    return unique_device_names

Input: ['lamp', 'lamp', 'tv', 'lamp']

Expected Output: ['lamp', 'lamp1', 'tv', 'lamp2']

My output: ['lamp', 'lamp1', 'lamp2', 'tv']

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • The reason you are losing the sequence is because Counter doesn’t maintain it - so iterate over `devicenames` to maintain the sequence and update `devices` and `unqiue_device_names`. – DisappointedByUnaccountableMod Jul 16 '20 at 06:59
  • Does this answer your question? [Python: Rename duplicates in list with progressive numbers without sorting list](https://stackoverflow.com/questions/30650474/python-rename-duplicates-in-list-with-progressive-numbers-without-sorting-list) – Tomerikoo Dec 09 '20 at 09:45

7 Answers7

1
devices = ['switch', 'tv', 'switch', 'tv', 'switch', 'tv']


def name_devices(device_list):
    unique_devices = []
    device_dict = {}
    for device in device_list:
        if device not in device_dict:
            device_dict[device] = 1
            unique_devices.append(device)
        else:
            updated_name = device + str(device_dict[device])
            unique_devices.append(updated_name)
            device_dict[device] = device_dict[device] + 1
    return unique_devices


result = name_devices(devices)
print(result)

Output: ['switch', 'tv', 'switch1', 'tv1', 'switch2', 'tv2']

Explanation: Use a hashmap to store the values you've seen you can keep a count of how many times you've seen it. So when you come across that second switch or tv you can take the number of times you've seen it already and concatenate it to the item string and put it into your result array.

Takes O(N) time and space complexity since we are traverse through the items array once and storing that info into a hashmap so it takes N time there.

saas1990
  • 35
  • 8
0

Using itertools.count

Ex:

from itertools import count


data = ['lamp','lamp','tv','lamp'] 
c = {i: count(0) for i in set(data)}    #For every item set initial count to 0
    
    
result = []
for i in data:
    n = next(c[i])
    if n == 0:
        result.append(i)
    else:
        result.append(f"{i}{n}")
print(result)

or

for i in data:
    n = next(c[i])
    result.append(i if n == 0 else f"{i}{n}")

Output:

['lamp', 'lamp1', 'tv', 'lamp2']
Rakesh
  • 81,458
  • 17
  • 76
  • 113
0

Maybe there is a better way by you can handle it by:

myList=['lamp','lamp','tv','lamp','tv','lamp']
dico={}
result=[]

for item in myList:
    if item in dico.keys():
        dico[item]+=1
        result.append(f"{item}{dico[item]}")
    else:
        dico[item]=0
        result.append(f"{item}")

result:

['lamp', 'lamp1', 'tv', 'lamp2', 'tv1', 'lamp3']

Renaud
  • 2,709
  • 2
  • 9
  • 24
0

Using dictionary:

def get_unique_device_names(names):
    d = {}
    unique_names = []
    for name in names:
        d[name] = d.get(name, 0)+1
        if d[name] > 1:
            unique_names.append("{}{}".format(name, d[name]-1))
        else:
            unique_names.append(name)
    return unique_names

if __name__ == "__main__":
    test_case = ['lamp','lamp','tv','lamp']
    expected_output = ['lamp','lamp1','tv','lamp2']
    output = get_unique_device_names(test_case)
    assert output == expected_output
    print(output)

Output:

['lamp', 'lamp1', 'tv', 'lamp2']

Explanation:

I have declared an empty dictionary and then gradually increased the number of occurrences of the devices from the given list. Then if a device has appeared more than once, I have added the number of occurrence - 1 to the unique device name list.

arshovon
  • 13,270
  • 9
  • 51
  • 69
0

This is my solution, it should work.

def nameDevices(devicelist):
    uniquedevices = []
    for i,device in enumerate(devicelist):
        occurence = devicelist[:i].count(device)
        if(occurence > 0):
            uniquedevices.append(device + str(occurence))
        else:
            uniquedevices.append(device)
    return uniquedevices
0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="result">Result : </div>
</body>
<script>
var presentDevice = ['tv', 'mobile', 'ac', 'mobile', 'laptop', 'laptop', 'laptop', 'mobile', 'tv', 'mobile', 'laptop', 'headphone', 'headphone', 'tv', 'tv'];
let uniqueDevice = [];
let deviceCount = [];
function getUniqueDevice() {
presentDevice.forEach(i => {
if (uniqueDevice.includes(i)) {
if (deviceCount.length > 0) {
 let filteObj = deviceCount.filter(o => o.name === i);
filteObj[0].len = filteObj[0].len + 1;
uniqueDevice.push(`${i}${filteObj[0].len}`);
}
} else {
obj = { name: i, len: 0 }
deviceCount.push(obj);
uniqueDevice.push(i);
}
})
document.getElementById('result').innerHTML = uniqueDevice.join(' ,');
}
getUniqueDevice();
</script>
</html> 
0

This works!

public static List<String> uniqNames(List<String> names) {

  HashMap<String, Integer> namesFrequency = new HashMap<>();

  List<String> result = new ArrayList<>();
  
  for (String name : names) {

    if (!namesFrequency.containsKey(name)) {
      namesFrequency.put(name, 1);
      result.add(name);
    }else { 

      int frequency = namesFrequency.get(name);
      result.add(name + String.valueOf(frequency));
      namesFrequency.put(name, namesFrequency.getOrDefault(name, 0) + 1);

    }
  }

  return result;
}