Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Reorder Data in Log Files in Python
Suppose we have an array of logs. In that array each entry is a space delimited string of words. The first word in each log is an alphanumeric identifier. Then, there are different types of strings like below −
- Each word after the id will consist only of lowercase letters;
- Each word after the id will consist only of digits.
We will call these two types of logs as letter-logs and digit-logs respectively. It is guaranteed that each log has at least one word after its id.
We have to reorder the logs so that all of the letter-logs stay before any digit-log. The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. Finally, the digit-logs should be put in their original order.
Problem Understanding
If the input is like logs = ["dig1 9 2 5 2","let1 art can","dig2 4 8","let2 own kit dig","let3 art zero"], then the output will be ["let1 art can","let3 art zero","let2 own kit dig","dig1 9 2 5 2","dig2 4 8"].
Algorithm Steps
To solve this, we will follow these steps −
-
words:= a new list for letter-logs -
nums:= a new list for digit-logs - For each log in logs, do:
- Split the log into words
- If second word is a digit, then insert log into nums
- Otherwise, store identifier and content separately in words array
- Sort the words array lexicographically by content, then by identifier
- Merge the sorted letter-logs with digit-logs and return
Implementation
class Solution:
def reorderLogFiles(self, logs):
words = []
nums = []
for log in logs:
s = log.split()
if s[1].isdigit():
nums.append(log)
else:
words.append((s[0], ' '.join(s[1:])))
# Sort by content first, then by identifier
words = sorted(words, key=lambda x: (x[1], x[0]))
words = [' '.join(w) for w in words]
return words + nums
# Test the solution
ob = Solution()
logs = ["dig1 9 2 5 2", "let1 art can", "dig2 4 8", "let2 own kit dig", "let3 art zero"]
result = ob.reorderLogFiles(logs)
print(result)
['let1 art can', 'let3 art zero', 'let2 own kit dig', 'dig1 9 2 5 2', 'dig2 4 8']
How It Works
The algorithm separates letter-logs and digit-logs into different lists. For letter-logs, it stores tuples of (identifier, content) to enable proper sorting. The sorting key (x[1], x[0]) ensures lexicographical ordering by content first, then by identifier for ties. Digit-logs maintain their original order by simply appending them to the result.
Step-by-Step Execution
def reorderLogFiles(logs):
words = []
nums = []
print("Processing logs:")
for log in logs:
s = log.split()
if s[1].isdigit():
nums.append(log)
print(f" Digit-log: {log}")
else:
words.append((s[0], ' '.join(s[1:])))
print(f" Letter-log: {log}")
print(f"\nBefore sorting: {words}")
words = sorted(words, key=lambda x: (x[1], x[0]))
print(f"After sorting: {words}")
words = [' '.join(w) for w in words]
return words + nums
# Example
logs = ["dig1 9 2 5 2", "let1 art can", "dig2 4 8", "let2 own kit dig", "let3 art zero"]
result = reorderLogFiles(logs)
print(f"\nFinal result: {result}")
Processing logs:
Digit-log: dig1 9 2 5 2
Letter-log: let1 art can
Digit-log: dig2 4 8
Letter-log: let2 own kit dig
Letter-log: let3 art zero
Before sorting: [('let1', 'art can'), ('let2', 'own kit dig'), ('let3', 'art zero')]
After sorting: [('let1', 'art can'), ('let3', 'art zero'), ('let2', 'own kit dig')]
Final result: ['let1 art can', 'let3 art zero', 'let2 own kit dig', 'dig1 9 2 5 2', 'dig2 4 8']
Conclusion
This solution efficiently separates letter-logs and digit-logs, sorts letter-logs lexicographically by content and identifier, while preserving the original order of digit-logs. The time complexity is O(n log n) due to sorting operations.
