6

How do I change the sequence of string? For e.g.

mys='4002-10-21'

Expected result:

'4002-21-10'

What I have tried:

I can enumerate the splitted string and then re-arrange the sequence like 1-3-2

newlist=list()
for i, v in enumerate(mys.split('-')):
    newlist.append(v)
5
  • 3
    So what's the problem with your approach? Commented Oct 15, 2017 at 14:49
  • are you trying to change dates from yyyy-mm-dd to yyyy-dd-mm? Commented Oct 15, 2017 at 14:52
  • @VanPeer Yes. I am trying to change date but it is part of pandas string object. So looking for string function. Commented Oct 15, 2017 at 14:55
  • This question would've received a more appropriate answer had you given it the pandas tag. None of these answers are exactly fit for adaptation into pandas code. Commented Nov 2, 2017 at 13:04
  • @shantanuo, I just discovered you wanted this to work in pandas. Please see my updated answer below, hope it helps you. Commented Nov 5, 2017 at 22:24

8 Answers 8

11

With operator.itemgetter you can get multiple items with a single call:

>>> from operator import itemgetter
>>> '-'.join(itemgetter(0,2,1)(mys.split('-')))
'4002-21-10'

With string format you can pick values from arguments:

>>> "{0}-{2}-{1}".format(*mys.split('-'))
'4002-21-10'

With re.sub you can capture groups and reorder them (assuming digits):

>>> import re
>>> re.sub(r'(\d+)-(\d+)-(\d+)', r'\1-\3-\2', mys)
'4002-21-10'

If you need this in pandas (as hinted in comments), you can use the regex-based approach in both DataFrame.replace and Series.str.replace, for example (add inplace=True for in-place subs):

>>> import pandas as pd
>>> df = pd.DataFrame({'dates': ['4002-10-21']})
>>> df.dates.replace(r'(\d+)-(\d+)-(\d+)', r'\1-\3-\2', regex=True)
0    4002-21-10
Name: dates, dtype: object
Sign up to request clarification or add additional context in comments.

Comments

9

If you're really trying to just reformat datetime string, I suggest you parse the string to a datetime object and format it as you wish:

import datetime                                                                                   

def rearrange(*args):                                                                             
    return [datetime.datetime.strptime(arg, '%Y-%m-%d').strftime('%Y-%d-%m') for arg in args]

>>> rearrange('4002-10-21', '4002-10-28')
['4002-21-10', '4002-28-10']  

Comments

3

Given the context of the question, your approach is fine:

mys = '4002-10-21'
parts = mys.split('-')
mys = parts[0] + '-' + parts[2] + '-' + parts[1]
print(mys)  # "4002-21-10"

It's brittle certainly, but if it's for a personal or one-off script, who cares? If you need more flexibility, then you'll need to describe more explicitly the nature of your constraints.

Comments

3

One good way is to use regular expressions this way the numbers which I presume can have different lengths eg: '4002-21-1' will also work fine.

    import re

    mys = '4002-21-10'

    parts = re.findall('[\d]+', mys) # finds all numbers that are next to each other
    print(parts) # just so you see what is created

    formatted_mys = parts[0] + "-" + parts[2] + "-" + parts[1] # put the parts together in the way you wanted

You can remove the print line if you wish of course. There are many others ways to do what you want but if you need it to be flexible this is what I would recommend.

Comments

3

Given:

mys='4002-10-21'

You can simply write up a function for it such as this:

def change_order(string, split_char, *args):
    string = string.split(split_char)

    new_list = []

    for i in args:
        try:
            new_list.append(string[i])  # change to i-1 for abstracted parameters
        except IndexError:
            return False

    return split_char.join(new_list)

Which given '4002-10-21' with an 1, 3, 2 (actual code takes 1 away because it's zero-indexed) reordering gives:

>>> test.change_order('4002-10-21', '-', 0, 2, 1)
'4002-21-10'

Comments

2

You can split on -, then re-join with - as the separator, but simply re-order as you need to:

>>> s = '4002-10-21'
>>> d = s.split('-')
>>> new_s = "-".join((d[0], d[2], d[1]))
'4002-21-10'

Or, without join, after you split, you can simply do:

new_s = "{}-{}-{}".format(d[0], d[2], d[1])

Comments

2

You can try this:

mys='4002-10-21'
m = mys.split("-")
new_mys = m[0]+"-"+'-'.join(m[1:][::-1])

Output:

'4002-21-10'

Comments

2
L='4002-10-21'
L=L.split("-")
L[i:3] = L[2:0:-1]
"-".join(L)

You could use slices.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.