How to implement switch statement in python

I want to write a function in Python that returns different fixed values based on the value of an input index.

In other languages I would use a switch or case statement, but Python does not appear to have a switch statement. What are the recommended Python solutions in this scenario?

share edit
 
22 
Related PEP, authored by Guido himself: PEP 3103  –    chb   Jun 16 '12 at 17:22
5 
@chb In that PEP, Guido doesn't mention that if/elif chains are also a classic source of error. It's a very fragile construct.  –    itsbruce   Jan 9 '14 at 13:46
2 
Missing from all solutions here is detection of duplicate case values. As a fail-fast principle, this may be a more important loss than performance or the fallthrough feature.  –    BobStein-VisiBone   Oct 17 '14 at 19:04

27 Answers

up vote 340 down vote accepted

You could use a dictionary:

def f(x):
    return {
        'a': 1,
        'b': 2,
    }[x]
share edit
 
10 
What happens if x is not found?  –    Nick   Sep 19 '08 at 15:46
12 
@nick: you can use defaultdict  –    Eli Bendersky   Sep 19 '08 at 17:38
7 
This is not a true switch/case... please see my response below  –    daniel   Sep 20 '08 at 20:21
149 
I'd recommend putting the dict outside of the function if performance is an issue, so it doesn't re-build the dict on every function call  –    Claudiu   Oct 23 '08 at 16:22
8 
@EliBendersky, Using the get method would probably be more normal than using acollections.defaultdict in this case.  –    Mike Graham   Feb 23 '12 at 16:38

If you'd like defaults you could use the dictionary "get" method:

def f(x):
    return {
        'a': 1,
        'b': 2,
        }.get(x, 9)    # 9 is default if x not found
share edit
 
4 
What if 'a' and 'b' match 1, and 'c' and 'd' match 2?  –    John Mee   Apr 9 '10 at 7:57
9 
@JM: Well, obviously dictionary lookups don't support fall-throughs. You could do a double dictionary lookup. I.e. 'a' & 'b' point to answer1 and 'c' and 'd' point to answer2, which are contained in a second dictionary.  –  Nick   Apr 9 '10 at 9:54
 
@AndersonGreen what is the issue here?  –    Quentin Pradet   Oct 2 '14 at 9:45
 
@QuentinPradet I was mistaken: there is no issue here. :)  –    Anderson Green   Oct 3 '14 at 1:43

Python Cookbook has several recipes (implementations and corresponding discussions) for switch statement. Please visit the following links:

  1. Readable switch construction without lambdas or dictionaries

  2. Exception-based Switch-Case

  3. Using a Dictionary in place of a 'switch' statement

share edit
 
31 
This deserves more upvotes. In particular, the first is awesome!  –    Casebash   Oct 24 '09 at 10:53
7 
That first one is clever, but is it Pythonic?  –    Craig McQueen   Nov 3 '09 at 3:13
13 
This answer would be better if it had something more than just links in it. Those links could go stale.  –    Caltor Nov 19 '12 at 23:15
4 
it looks nice in the code but... KISS! I'll keep using if/elseif  –    KurzedMetal   May 31 '13 at 14:22  
3 
Please make your answer stand on its own!  –    minitech   Dec 14 '13 at 23:04

I've always liked doing it this way

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

From here

share edit
 
4 
great method, combined with get() to handle default is my best choice too  –    AlberT   Sep 2 '09 at 16:11
3 
He's asking for fixed values. Why generate a function to calculate something when it's a lookup? Interesting solution for other problems though.  –    Nick   Jan 21 '10 at 17:06
7 
it maybe isn't a good idea to use lambda in this case because lambda is actually called each time the dictionary is built.  –    Asher   Apr 22 '12 at 21:48
2 
Sadly this is the closest people are going to get. Methods which use .get() (like the current highest answers) will need to eagerly evaluate all possibilities before dispatching, and therefore not only are (not just very but) extremely inefficient and also cannot have side-effects; this answer gets around that issue, but is more verbose. I would just use if/elif/else, and even those take just as long to write as 'case'.  –    ninjagecko Mar 17 '14 at 13:48  
 
wouldn't this evaluate all the functions/lambdas every time in all cases, even if it is only returning one of the results?  –    slf   Aug 6 '14 at 19:04

In addition to the dictionary methods (which I really like, BTW), you can also use if-elif-else to obtain the switch/case/default functionality:

if x=='a':
    # Do the thing
elif x=='b':
    # Do the other thing
else:
    # Do the default

This of course is not identical to switch/case - you cannot have fall-through as easily as leaving off the break; statement, but you can have a more complicated test. It's formatting is nicer than a series of nested ifs, even though functionally that's what it is closer to.

share edit
 
11 
i'd really prefer this, it uses a standart language construct and doesn't throw a KeyError if no matching case is found  –    martyonair   May 18 '13 at 10:30
class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))

Usage:

while switch(n):
    if case(0):
        print "You typed zero."
        break
    if case(1, 4, 9):
        print "n is a perfect square."
        break
    if case(2):
        print "n is an even number."
    if case(2, 3, 5, 7):
        print "n is a prime number."
        break
    if case(6, 8):
        print "n is an even number."
        break
    print "Only single-digit numbers are allowed."
    break

Tests:

n = 2
#Result:
#n is an even number.
#n is a prime number.
n = 11
#Result:
#Only single-digit numbers are allowed.
share edit
 
12 
This is not threat safe. If several switches are hit at the same time all switches take the value of the last switch.  –    francescortiz   Jun 26 '13 at 16:35  

There's a pattern that I learned from Twisted Python code.

class SMTP:
    def lookupMethod(self, command):
        return getattr(self, 'do_' + command.upper(), None)
    def do_HELO(self, rest):
        return 'Howdy ' + rest
    def do_QUIT(self, rest):
        return 'Bye'

SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com'
SMTP().lookupMethod('QUIT')('') # => 'Bye'

You can use it any time you need to dispatch on a token and execute extended piece of code. In a state machine you would have  state_  methods, and dispatch on self.state. This switch can be cleanly extended by inheriting from base class and defining your own  do_  methods. Often times you won't even have  do_  methods in the base class.

Edit: how exactly is that used

In case of SMTP you will receive HELO from the wire. The relevant code (from twisted/mail/smtp.py, modified for our case) looks like this

class SMTP:
    # ...

    def do_UNKNOWN(self, rest):
        raise NotImplementedError, 'received unknown command'

    def state_COMMAND(self, line):
        line = line.strip()
        parts = line.split(None, 1)
        if parts:
            method = self.lookupMethod(parts[0]) or self.do_UNKNOWN
            if len(parts) == 2:
                return method(parts[1])
            else:
                return method('')
        else:
            raise SyntaxError, 'bad syntax'

SMTP().state_COMMAND('   HELO   foo.bar.com  ') # => Howdy foo.bar.com

You'll receive ' HELO foo.bar.com ' (or you might get 'QUIT' or 'RCPT TO: foo'). This is tokenized into parts as ['HELO', 'foo.bar.com']. The actual method lookup name is taken from parts[0].

(The original method is also called state_COMMAND, because it uses the same pattern to implement a state machine, i.e. getattr(self, 'state_' + self.mode))

share edit
 
 
I don't see the benefit from this pattern over just calling the methods directly: SMTP().do_HELO('foo.bar.com') OK, there can be common code in the lookupMethod, but since that also can be overwritten by the subclass I don't see what you gain from the indirection.  –    Mr Shark   Sep 13 '08 at 11:35
 
You wouldn't know what method to call in advance, that is to say 'HELO' comes from a variable. i've added usage example to the original post  –    user6205   Sep 13 '08 at 17:45
 
May I suggest simply: eval('SMTP().do_' + command)('foo.bar.com')  –    jforberg   Jun 21 '11 at 17:32  
 
Also, why instantiate a new SMTP object for each method call? That's what global functions are for.  –  jforberg   Jun 21 '11 at 17:34  
1 
eval? seriously? and instead of instantiating one method per call, we can very well instantiate once and use it in all calls provided it has no internal state.  –    Mahesh   Mar 19 '13 at 18:10

My favorite one is a really nice recipe. You'll really like it. It's the closest one I've seen to actual switch case statements, especially in features.

Here's an example:

# The following example is pretty much the exact use-case of a dictionary,
# but is included for its simplicity. Note that you can include statements
# in each suite.
v = 'ten'
for case in switch(v):
    if case('one'):
        print 1
        break
    if case('two'):
        print 2
        break
    if case('ten'):
        print 10
        break
    if case('eleven'):
        print 11
        break
    if case(): # default, could also just omit condition or 'if True'
        print "something else!"
        # No need to break here, it'll stop anyway

# break is used here to look as much like the real thing as possible, but
# elif is generally just as good and more concise.

# Empty suites are considered syntax errors, so intentional fall-throughs
# should contain 'pass'
c = 'z'
for case in switch(c):
    if case('a'): pass # only necessary if the rest of the suite is empty
    if case('b'): pass
    # ...
    if case('y'): pass
    if case('z'):
        print "c is lowercase!"
        break
    if case('A'): pass
    # ...
    if case('Z'):
        print "c is uppercase!"
        break
    if case(): # default
        print "I dunno what c was!"

# As suggested by Pierre Quentel, you can even expand upon the
# functionality of the classic 'case' statement by matching multiple
# cases in a single shot. This greatly benefits operations such as the
# uppercase/lowercase example above:
import string
c = 'A'
for case in switch(c):
    if case(*string.lowercase): # note the * for unpacking as arguments
        print "c is lowercase!"
        break
    if case(*string.uppercase):
        print "c is uppercase!"
        break
    if case('!', '?', '.'): # normal argument passing style also applies
        print "c is a sentence terminator!"
        break
    if case(): # default
        print "I dunno what c was!"
share edit
 
2 
I would substitute for case in switch() with with switch() as case, makes more sense, since it need s to run only once.  –    skyjur   Dec 12 '13 at 16:24
1 
@Skirmantas: Note that with doesn’t allow for break though, so the fallthrough option is taken away.  –  Jonas Wielicki   May 8 '14 at 16:53  
 
Apologies for not putting more effort in to determine this myself: a similar answer above is not thread safe. Is this?  –    David Winiecki   Sep 12 '14 at 15:47

A true switch/case in Python is going to be more difficult than a dictionary method or if/elif/else methods because the simple versions do not support fall through.

Another downfall of the if/elif/else method is the need for repeated comparisons.

The C implementation of a switch/case has a performance benefit over if/else if/else in that only a single comparison is needed. The result of that comparison is used as an offset into a jump table (in the underlying asm generated).

Mimicking the true functionality in Python would be a pain. Does any one have an implementation that would allow for fall through while only using a single comparison?

share edit
 
31 
I suppose that point of view depends on whether you consider fall-through to be a feature or not.  –  Greg Hewgill   Sep 21 '08 at 1:29
2 
Yes, some languages support switches that do not even allow fall through (C# does not for example, although it does allow multiple mappings, which explains why it still requires "break;")  –    TM.   Nov 27 '08 at 4:41
10 
He doesn't need a switch statement. "I want to write a function in python that returns different fixed values based on the value of an input index." If you need fall through support to do that, you're doing something wrong.  –    Wallacoloo   May 15 '10 at 23:24
12 
As this stands right now this is more of a question then an answer.  –    James McMahon   Oct 3 '12 at 19:32
3 
@GregHewgill it absolutely is a feature and a useful one.  –    daniel   Feb 15 '13 at 2:22

Let's say you don't want to just return a value, but want to use methods that change something on an object. Using the approach stated here would be:

result = {
  'a': obj.increment(x),
  'b': obj.decrement(x)
}.get(value, obj.default(x))

What happens here is that python evaluates all methods in the dictionary. So even if your value is 'a', the object will get incremented and decremented by x.

Solution:

func, args = {
  'a' : (obj.increment, (x,)),
  'b' : (obj.decrement, (x,)),
}.get(value, (obj.default, (x,)))

result = func(*args)

So you get a list containing a function and its arguments. This way, only the function pointer and the argument list get returned, not evaluated. 'result' then evaluates the returned function call.

share edit
 

If you're searching extra-statement, as "switch", I built a python module that extends Python. It's called ESPY as "Enhanced Structure for Python" and it's available for both Python 2.x and Python 3.x.

For example, in this case, a switch statement could be performed by the following code:

macro switch(arg1):
    while True:
        cont=False
        val=%arg1%
        socket case(arg2):
            if val==%arg2% or cont:
                cont=True
                socket
        socket else:
            socket
        break

that can be used like this:

a=3
switch(a):
    case(0):
        print("Zero")
    case(1):
        print("Smaller than 2"):
        break
    else:
        print ("greater than 1")

so espy translate it in Python as:

a=3
while True:
    cont=False
    if a==0 or cont:
        cont=True
        print ("Zero")
    if a==1 or cont:
        cont=True
        print ("Smaller than 2")
        break
    print ("greater than 1")
    break
share edit
 
 
Very cool, but what's the point of the while True: at the top of the generated Python code? It'll inevitably hit the break at the bottom of the generated Python code, so it seems to me that both the while True: andbreak could be removed. Further, is ESPY smart enough to change the name of cont if the user uses that same name in their own code? In any event, I want to use vanilla Python so I won't use this, but it's cool none-the-less. +1 for sheer coolness.  –    ArtOfWarfare   Jun 29 '14 at 12:56  

expanding on the "dict as switch" idea. if you want to use a default value for your switch:

def f(x):
    try:
        return {
            'a': 1,
            'b': 2,
        }[x]
    except KeyError:
        return 'default'
share edit
 
8 
I think it's clearer to use .get() on the dict with the default specified. I prefer to leave Exceptions for exceptional circumstances, and it cuts three lines of code and a level of indentation without being obscure.  –    Chris B.   Jun 5 '09 at 15:14
5 
This is an exceptional circumstance. It may or may not be a rare circumstance depending on useful, but it's definitely an exception (fall back on 'default') from the rule (get something from this dict). By design, Python programs use exceptions at the drop of a hat. That being said, using get could potentially make the code a bit nicer.  –    Mike Graham   Mar 26 '10 at 16:49

If you have a complicated case block you can consider using a function dictionary lookup table...

If you haven't done this before its a good idea to step into your debugger and view exactly how the dictionary looks up each function.

NOTE: Do not use "()" inside the case/dictionary lookup or it will call each of your functions as the dictionary / case block is created. Remember this because you only want to call each function once using a hash style lookup.

def first_case():
    print "first"

def second_case():
    print "second"

def third_case():
    print "third"

mycase = {
'first': first_case, #do not use ()
'second': second_case, #do not use ()
'third': third_case #do not use ()
}
myfunc = mycase['first']
myfunc()
share edit
 
 
Surely this is the way to do it (for when switch is used for more than just: look up value in dictionary!), worth noting you have to be carefully consider scope.  –    Andy Hayden   Sep 23 '12 at 16:11
 
Right... I updated this.  –    Asher   Oct 17 '12 at 21:53

The solutions I use:

A combination of 2 of the solutions posted here, which is relatively easy to read and supports defaults.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}.get(whatToUse, lambda x: x - 22)(value)

where

.get('c', lambda x: x - 22)(23)

looks up "lambda x: x - 2" in the dict and uses it with x=23

.get('xxx', lambda x: x - 22)(44)

doesn't find it in the dict and uses the default "lambda x: x - 22" with x=44.

share edit
 

I would just use if/elif/else statements. I think that it's good enough to replace the switch statement.

share edit
 

I didn't find the simple answer I was looking for anywhere on Google search. But I figured it out anyway. It's really quite simple. Decided to post it, and maybe prevent a few less scratches on someone else's head. The key is simply "in" and tuples. Here is the switch statement behavior with fall-through, including RANDOM fall-through.

l = ['Dog', 'Cat', 'Bird', 'Bigfoot',
     'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster']

for x in l:
    if x in ('Dog', 'Cat'):
        x += " has four legs"
    elif x in ('Bat', 'Bird', 'Dragonfly'):
        x += " has wings."
    elif x in ('Snake',):
        x += " has a forked tongue."
    else:
        x += " is a big mystery by default."
    print(x)

print()

for x in range(10):
    if x in (0, 1):
        x = "Values 0 and 1 caught here."
    elif x in (2,):
        x = "Value 2 caught here."
    elif x in (3, 7, 8):
        x = "Values 3, 7, 8 caught here."
    elif x in (4, 6):
        x = "Values 4 and 6 caught here"
    else:
        x = "Values 5 and 9 caught in default."
    print(x)

Provides:

Dog has four legs
Cat has four legs
Bird has wings.
Bigfoot is a big mystery by default.
Dragonfly has wings.
Snake has a forked tongue.
Bat has wings.
Loch Ness Monster is a big mystery by default.

Values 0 and 1 caught here.
Values 0 and 1 caught here.
Value 2 caught here.
Values 3, 7, 8 caught here.
Values 4 and 6 caught here
Values 5 and 9 caught in default.
Values 4 and 6 caught here
Values 3, 7, 8 caught here.
Values 3, 7, 8 caught here.
Values 5 and 9 caught in default.
share edit
 
 
Where exactly is fallthrough here?  –    Jonas Wielicki   May 8 '14 at 16:56
 
switch(n){ case  –    JD Graham   Jul 30 '14 at 4:46
 
Oops! There is fall through there, but I'm not contributing to Stack Overflow anymore. Don't like THEM at all. I like the contributions by others, but just not Stackoverflow. If you're using fall through for FUNCTIONALITY then you want to CATCH certain conditions in all in one case statement in a switch (a catch all), until you reach a break statement in a switch.  –    JD Graham   Jul 30 '14 at 4:58
 
Here both the values "Dog" and "Cat" FALL THROUGH and are handled by the SAME functionality, which is they are defined as having "four legs." It's an ABSTRACT equivalent to fall through and different values handled by the SAME case statement where a break occurs.  –    JD Graham   Jul 30 '14 at 5:16  

I have made a (relatively) flexible and re-usable solution for this. It can be found at GitHub as this gist. If the result of the switch function is callable, it is automatically called.

share edit
 

If you are really just returning a predetermined, fixed value, you could create a dictionary with all possible input indexes as the keys, along with their corresponding values. Also, you might not really want a function to do this - unless you're computing the return value somehow.

Oh, and if you feel like doing something switch-like, see here.

share edit
 
 
The link seems invalidated.  –    GingerPlusPlus   Nov 5 '14 at 17:43

Defining:

def switch1(value, options):
  if value in options:
    options[value]()

allows you to use a fairly straightforward syntax, with the cases bundled into a map:

def sample1(x):
  local = 'betty'
  switch1(x, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye," + local),
      print("!")),
    })

I kept trying to redefine switch in a way that would let me get rid of the "lambda:", but gave up. Tweaking the definition:

def switch(value, *maps):
  options = {}
  for m in maps:
    options.update(m)
  if value in options:
    options[value]()
  elif None in options:
    options[None]()

Allowed me to map multiple cases to the same code, and to supply a default option:

def sample(x):
  switch(x, {
    _: lambda: print("other") 
    for _ in 'cdef'
    }, {
    'a': lambda: print("hello"),
    'b': lambda: (
      print("goodbye,"),
      print("!")),
    None: lambda: print("I dunno")
    })

Each replicated case has to be in its own dictionary; switch() consolidates the dictionaries before looking up the value. It's still uglier than I'd like, but it has the basic efficiency of using a hashed lookup on the expression, rather than a loop through all the keys.

share edit
 

I liked Mark Bies's answer, but I am getting error. So modified it to run in a comprehensible way.

In [1]:  result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }['a'](x)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-79-5ce2b3ae3711> in <module>()
      3   'b': lambda x: 'B',
      4   'c': lambda x: 'C'
----> 5 }['a'](x)

NameError: name 'x' is not defined

Input 2 works but in a weird way. I have to run with results[value](value)

In [2]: result = {
    ...:   'a': lambda x: 'A',
    ...:   'b': lambda x: 'B',
    ...:   'c': lambda x: 'C'
    ...: }
    ...: result['a']('a')
    ...: 
Out[2]: 'A'

Input 3 works in a comprehensible way. I use this with result[value]()

In [3]: result = {
    ...:   'a': lambda : 'A',
    ...:   'b': lambda : 'B',
    ...:   'c': lambda : 'C',
    ...:   None: lambda : 'Nothing else matters'

    ...: }
    ...: result['a']()
    ...: 
Out[3]: 'A'

Edit: I noticed that i can use None type with with dictionaries. So this would emulate switch ; case else

share edit
 
 
Doesn't the None case emulate simply result[None]() ?  –    BobStein-VisiBone   Mar 11 at 15:19
 
Yes, exactly. I mean result = {'a': 100, None:5000}; result[None]  –    guneysus   Mar 11 at 15:52  
 
Just checking that no one is thinking None: behaves like default:.  –    BobStein-VisiBone   Mar 11 at 16:54

I found that a common switch structure:

switch ...parameter...
case p1: v1; break;
case p2: v2; break;
default: v3;

can be expressed in Python as follows:

(lambda x: v1 if p1(x) else v2 if p2(x) else v3)

or formatted in a clearer way:

(lambda x:
     v1 if p1(x) else
     v2 if p2(x) else
     v3)

The python version is an expression, which evaluates to a value, instead of a statement.

share edit
 
 
Also instead of ...parameter... and p1(x) how about parameter and p1==parameter  –    BobStein-VisiBone Mar 11 at 15:28
 
@BobStein-VisiBone hi, here is an example that runs in my python session: f = lambda x: 'a' if x==0 else 'b' if x==1 else 'c'. When I later called f(2), I got 'c'f(1)'b'; and f(0)'a'. As for p1(x), it denotes a predicate; as long as it returns True or False, no matter it is a function call or a expression, it's fine.  –    leo   Mar 13 at 16:16  
 
@BobStein-VisiBone Yes, you are right! Thank :) For the multi-line expression to work, parentheses should be placed, either as in your suggestion, or as in my modified example.  –    leo   Mar 14 at 5:16  
 
Excellent. Now I'll delete all my comments about the parens.  –    BobStein-VisiBone   Mar 14 at 20:48
def f(x):
     return 1 if x == 'a' else\
            2 if x in 'bcd' else\
            0 #default

Short and easy to read, has a default value and supports expressions in both conditions and return values.

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下 4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值